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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
use std::future::Future;
use crate::{
engine::d2,
foundation::{Key, TargetPlatform},
services::AssetBundle,
ui::{Codec, Locale, Size, TextDirection},
};
pub struct ImageConfiguration {
// The preferred AssetBundle to use if the ImageProvider needs one and does not have one already selected.
pub bundle: Option<Box<dyn AssetBundle>>,
// The device pixel ratio where the image will be shown.
pub device_pixel_ratio: Option<f32>,
// The language and region for which to select the image.
pub locale: Option<Locale>,
// The TargetPlatform for which assets should be used.
// This allows images to be specified in a platform-neutral fashion yet use different assets on different platforms,
// to match local conventions e.g. for color matching or shadows.
pub platform: Option<TargetPlatform>,
// The size at which the image will be rendered.
pub size: Option<Size>,
// The reading direction of the language for which to select the image.
pub text_direction: Option<TextDirection>,
}
impl Default for ImageConfiguration {
fn default() -> Self {
Self {
bundle: Default::default(),
device_pixel_ratio: Default::default(),
locale: Default::default(),
platform: Default::default(),
size: Default::default(),
text_direction: Default::default(),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct ImageInfo {
// The raw image pixels.
pub image: d2::Image,
// The linear scale factor for drawing this image at its intended size.
pub scale: f32,
// The size of raw image pixels in bytes.
pub size_bytes: i32,
}
impl ImageInfo {
// Creates an ImageInfo with a cloned image.
pub fn clone() -> ImageInfo {
todo!()
}
// Disposes of this object.
pub fn dispose() {}
// Whether this ImageInfo is a clone of the other.
pub fn is_clone_of(other: ImageInfo) -> bool {
todo!()
}
}
pub struct ImageChunkEvent {
// The number of bytes that have been received across the wire thus far.
pub cumulative_bytes_loaded: i32,
// The expected number of bytes that need to be received to finish loading the image.
pub expected_total_bytes: Option<i32>,
}
// Fn(ImageChunkEvent event)
pub type ImageChunkListener = dyn FnMut(ImageChunkEvent);
// Fn(image: ImageInfo, synchronous_call: bool)
pub type ImageListener = dyn FnMut(ImageInfo, bool);
#[allow(dead_code)]
pub struct ImageStreamListener {
// Callback for getting notified when a chunk of bytes has been received during the loading of the image.
on_chunk: Option<Box<ImageChunkListener>>,
// Callback for getting notified when an error occurs while loading an image.
on_error: Option<Box<ImageErrorListener>>,
// Callback for getting notified that an image is available.
on_image: Box<ImageListener>,
}
impl ImageStreamListener {
pub fn new(
on_image: Box<ImageListener>,
on_chunk: Option<Box<ImageChunkListener>>,
on_error: Option<Box<ImageErrorListener>>,
) -> Self {
Self {
on_chunk,
on_error,
on_image,
}
}
}
impl Default for ImageStreamListener {
fn default() -> Self {
Self {
on_chunk: Default::default(),
on_error: Default::default(),
on_image: box |_, _| {}, // NullObject
}
}
}
#[allow(dead_code)]
pub struct ImageStream {
// The completer that has been assigned to this image stream.
pub completer: Option<ImageStreamCompleter>,
// Returns an object which can be used with == to determine if this ImageStream shares the same listeners list as another ImageStream.
pub key: Key,
// KISS
pub image: Option<d2::Image>,
}
impl ImageStream {
// Adds a listener callback that is called whenever a new concrete ImageInfo object is available.
// If a concrete image is already available, this object will call the listener synchronously.
pub fn add_listener(&self, listener: ImageStreamListener) {
if let Some(image) = self.image {
let mut handle = listener.on_image;
handle(
ImageInfo {
image,
scale: 1.0,
size_bytes: 0,
},
true,
)
}
}
// Stops listening for events from this stream's ImageStreamCompleter.
pub fn remove_listener(&self, listener: ImageStreamListener) {}
// Assigns a particular ImageStreamCompleter to this ImageStream.
pub fn set_completer(&self, value: ImageStreamCompleter) {}
}
impl Default for ImageStream {
fn default() -> Self {
Self {
completer: Default::default(),
key: Default::default(),
image: Default::default(),
}
}
}
pub struct ImageCacheStatus {
// An image that has been submitted to ImageCache.putIfAbsent, has completed, fits based on the sizing rules of the cache, and has not been evicted.
pub keep_alive: bool,
// An image that has been submitted to ImageCache.putIfAbsent and has at least one listener on its ImageStreamCompleter.
pub live: bool,
// An image that has been submitted to ImageCache.putIfAbsent, but not yet completed.
pub pending: bool,
// An image that is tracked in some way by the ImageCache, whether pending, keepAlive, or live.
pub tracked: bool,
// An image that either has not been submitted to ImageCache.putIfAbsent or has otherwise been evicted from the keepAlive and live caches.
pub untracked: bool,
}
// impl<T: Default> Default for ImageProvider<T> {
// fn default() -> Self {
// Self(Default::default())
// }
// }
pub struct ImageCache {
// The current number of cached entries.
pub current_size: i32,
// The current size of cached entries in bytes.
pub current_size_bytes: i32,
// The number of live images being held by the ImageCache.
pub live_image_count: i32,
// Maximum number of entries to store in the cache.
pub maximum_size: i32,
// Maximum size of entries to store in the cache in bytes.
pub maximum_size_bytes: i32,
// The number of images being tracked as pending in the ImageCache.
pub pending_image_count: i32,
}
impl ImageCache {
// Evicts all pending and keepAlive entries from the cache.
pub fn clear() {}
// Clears any live references to images in this cache.
pub fn clear_live_images() {}
// Returns whether this key has been previously added by putIfAbsent.
pub fn contains_key(key: Key) -> bool {
todo!()
}
// Evicts a single entry from the cache, returning true if successful.
pub fn evict(key: Key, include_live: bool /* = true*/) -> bool {
todo!()
}
// Returns the previously cached ImageStream for the given key, if available;
// if not, calls the given callback to obtain it first. In either case, the key is moved to the 'most recently used' position.
pub fn put_if_absent(
key: Key,
loader: ImageStreamCompleter,
on_error: Option<Box<ImageErrorListener>>,
) -> Option<ImageStreamCompleter> {
todo!()
}
// The ImageCacheStatus information for the given key.
pub fn status_for_key(key: Key) -> ImageCacheStatus {
todo!()
}
}
// impl<T: Default> Default for ImageProvider<T> {
// fn default() -> Self {
// Self(Default::default())
// }
// }
#[allow(dead_code)]
pub struct ImageStreamCompleter {
// Whether any listeners are currently registered.
has_listeners: bool,
}
impl ImageStreamCompleter {
// Adds a listener callback that is called whenever a new concrete ImageInfo object is available or an error is reported.
// If a concrete image is already available, or if an error has been already reported,
// this object will notify the listener synchronously.
pub fn add_listener(listener: ImageStreamListener) {}
// Adds a callback to call when removeListener results in an empty list of listeners and there are no keepAlive handles outstanding.
pub fn add_on_last_listener_removed_callback(callback: Box<dyn Fn()>) {}
// // Creates an ImageStreamCompleterHandle that will prevent this stream from being disposed at least until the handle is disposed.
// pub fn keep_alive() -> ImageStreamCompleterHandle {
// todo!()
// }
// Stops the specified listener from receiving image stream events.
pub fn remove_listener(listener: ImageStreamListener) {}
// Removes a callback previously supplied to addOnLastListenerRemovedCallback.
pub fn remove_on_last_listener_removed_callback(callback: Box<dyn Fn()>) {}
// // Calls all the registered error listeners to notify them of an error that occurred while resolving the image.
// pub fn report_error(
// context: Option<DiagnosticsNode>,
// exception: Object,
// stack: Option<StackTrace>,
// information_collector: Option<InformationCollector>,
// silent: bool, /*= false*/
// ) {
// }
// Calls all the registered ImageChunkListeners (listeners with an ImageStreamListener.onChunk specified) to notify them of a new ImageChunkEvent.
pub fn report_image_chunk_event(event: ImageChunkEvent) {}
// Calls all the registered listeners to notify them of a new image.
pub fn set_image(image: ImageInfo) {}
}
impl Default for ImageStreamCompleter {
fn default() -> Self {
Self {
has_listeners: Default::default(),
}
}
}
// Fn(bytes: Uint8List, cache_width: Option<i32>, cache_height: Option<i32>, allow_upscaling: bool) -> impl Future<Codec>
pub type DecoderCallback =
dyn Fn(&[u8], Option<i32>, Option<i32>, bool) -> Box<dyn Future<Output = Codec>>;
// Fn(exception: Object, stack_trace: Option<StackTrace>)
pub type ImageErrorListener = dyn Fn();
// Key is Generic here
pub trait ImageProvider /*<T>*/ {
// Called by resolve to create the ImageStream it returns.
fn create_stream(&self, configuration: ImageConfiguration) -> ImageStream;
// Evicts an entry from the image cache.
fn evict(
&self,
cache: Option<ImageCache>,
configuration: ImageConfiguration, /*= ImageConfiguration.empty*/
) -> Box<dyn Future<Output = bool>>;
// Converts a key into an ImageStreamCompleter, and begins fetching the image.
fn load(&self, key: Key, decode: Box<DecoderCallback>) -> ImageStreamCompleter;
// Returns the cache location for the key that this ImageProvider creates.
fn obtain_cache_status(
&self,
configuration: ImageConfiguration,
handle_error: Option<Box<ImageErrorListener>>,
) -> Box<dyn Future<Output = Option<ImageCacheStatus>>>;
// Converts an ImageProvider's settings plus an ImageConfiguration to a key that describes the precise image to load.
fn obtain_key(&self, configuration: ImageConfiguration) -> Box<dyn Future<Output = Key>>;
// Resolves this image provider using the given configuration, returning an ImageStream.
fn resolve(&self, configuration: ImageConfiguration) -> ImageStream;
// Called by resolve with the key returned by obtainKey.
fn resolve_stream_for_key(
&self,
configuration: ImageConfiguration,
stream: ImageStream,
key: Key,
handle_error: Option<Box<ImageErrorListener>>,
);
}