1use anyhow::Result;
38use lazy_static::lazy_static;
39use std::any::TypeId;
40use std::collections::HashMap;
41use std::sync::{Arc, Mutex};
42
43extern crate self as fission_core;
44
45pub mod action;
46pub mod async_runtime;
47pub mod build;
48mod build_context;
49pub mod capability; pub mod context; pub mod data_stream;
52pub mod diff;
53pub mod effect; pub mod env;
55pub mod event;
56pub mod hit_test;
57pub mod input;
58pub(crate) mod lowering;
59pub mod media;
60pub mod motion;
61pub mod platform;
62pub mod platform_barcode;
63pub mod platform_biometric;
64pub mod platform_bluetooth;
65pub mod platform_camera;
66pub mod platform_clipboard;
67pub mod platform_geolocation;
68pub mod platform_haptics;
69pub mod platform_microphone;
70pub mod platform_nfc;
71pub mod platform_passkey;
72pub mod platform_volume;
73pub mod platform_wifi;
74pub mod registry;
75pub mod runtime;
76pub mod scoped_action_handlers;
77pub mod scrollbar;
78pub mod state;
79pub mod time;
80pub mod ui;
81
82pub mod view;
83
84#[doc(hidden)]
85pub mod internal {
92 pub use crate::build_context::BuildCtx;
93 pub use crate::lowering::{
94 build_layout_tree, wrap_zstack_child, InternalIrBuilder, InternalLoweringCx,
95 };
96 use crate::Widget;
97 use fission_ir::WidgetId;
98
99 pub fn custom_render_widget(node: InternalRenderNode) -> Widget {
100 Widget::custom(node)
101 }
102
103 pub fn lower_widget(widget: &Widget, cx: &mut InternalLoweringCx) -> WidgetId {
104 let root = cx.next_widget_root();
105 lower_widget_with_root(widget, cx, root)
106 }
107
108 pub fn lower_widget_with_root(
109 widget: &Widget,
110 cx: &mut InternalLoweringCx,
111 root: WidgetId,
112 ) -> WidgetId {
113 widget.clone().resolve_identities(root).lower(cx)
114 }
115
116 pub fn lower_widget_to_ir(widget: &Widget) -> fission_ir::CoreIR {
117 lower_widget_to_ir_with_root(widget, WidgetId::app_root())
118 }
119
120 pub fn lower_widget_to_ir_with_root(widget: &Widget, root: WidgetId) -> fission_ir::CoreIR {
121 let env = crate::Env::default();
122 let runtime_state = crate::RuntimeState::default();
123 let mut cx = InternalLoweringCx::new(&env, &runtime_state, None, None);
124 let root_id = widget.clone().resolve_identities(root).lower(&mut cx);
125 cx.ir.root = Some(root_id);
126 cx.ir
127 }
128
129 pub fn resolve_widget_identities(widget: &Widget, root: WidgetId) -> Widget {
130 widget.clone().resolve_identities(root)
131 }
132
133 pub fn shell_root_id(authored_root: WidgetId) -> WidgetId {
134 WidgetId::derived(authored_root.as_u128(), &[0xF155_5E11])
135 }
136
137 pub fn widget_id(widget: &Widget) -> Option<WidgetId> {
138 widget.declared_id()
139 }
140
141 pub fn widget_kind_name(widget: &Widget) -> &'static str {
142 widget.kind_name()
143 }
144
145 pub fn widget_as_row(widget: &Widget) -> Option<&crate::ui::Row> {
146 widget.as_row()
147 }
148
149 pub fn widget_as_column(widget: &Widget) -> Option<&crate::ui::Column> {
150 widget.as_column()
151 }
152
153 pub fn widget_as_container(widget: &Widget) -> Option<&crate::ui::Container> {
154 widget.as_container()
155 }
156
157 pub fn widget_as_scroll(widget: &Widget) -> Option<&crate::ui::Scroll> {
158 widget.as_scroll()
159 }
160
161 pub fn widget_as_rich_text(widget: &Widget) -> Option<&crate::ui::RichText> {
162 widget.as_rich_text()
163 }
164
165 pub fn widget_as_text(widget: &Widget) -> Option<&crate::ui::Text> {
166 widget.as_text()
167 }
168
169 pub fn widget_as_text_input(widget: &Widget) -> Option<&crate::ui::TextInput> {
170 widget.as_text_input()
171 }
172
173 pub fn widget_as_button(widget: &Widget) -> Option<&crate::ui::Button> {
174 widget.as_button()
175 }
176
177 pub fn widget_as_gesture_detector(widget: &Widget) -> Option<&crate::ui::GestureDetector> {
178 widget.as_gesture_detector()
179 }
180
181 #[cfg(feature = "interactive-canvas")]
182 pub fn widget_as_interactive_viewer(widget: &Widget) -> Option<&crate::ui::InteractiveViewer> {
183 widget.as_interactive_viewer()
184 }
185
186 pub fn widget_as_zstack(widget: &Widget) -> Option<&crate::ui::ZStack> {
187 widget.as_zstack()
188 }
189
190 pub use crate::ui::custom_render::{
191 downcast_render_object, CustomEventResult, CustomHitResult, CustomRender,
192 CustomRenderObject,
193 };
194 pub use crate::ui::node::{CustomWidget, InternalRenderNode};
195 pub use crate::ui::traits::{InternalLower, InternalLowerer};
196}
197
198pub mod public {
199 pub mod action {
200 pub use crate::action::*;
201 }
202 pub mod env {
203 pub use crate::env::*;
204 }
205 pub mod event {
206 pub use crate::event::*;
207 }
208 pub mod hit_test {
209 pub use crate::hit_test::*;
210 }
211 pub mod registry {
212 pub use crate::registry::*;
213 }
214 pub mod scoped_action_handlers {
215 pub use crate::scoped_action_handlers::*;
216 }
217 pub mod ui {
218 pub use crate::ui::widgets::*;
219 pub use crate::ui::Widget;
220
221 pub mod widgets {
222 pub use crate::ui::widgets::*;
223 }
224 }
225 pub mod view {
226 pub use crate::view::*;
227 }
228
229 pub use crate::action::{
230 Action, ActionEnvelope, ActionId, ActionScopeId, GlobalState, UpdateTextInput,
231 };
232 pub use crate::async_runtime::{
233 BoxFuture, JobCtx, JobRef, JobSpec, ResourceExecutionContext, ServiceBindings, ServiceCtx,
234 ServiceRunner, ServiceSlot, ServiceSpec, ServiceType,
235 };
236 pub use crate::capability::{
237 CapabilityCtx, CapabilityInvocationPayload, CapabilityType, OpenUrlCapability,
238 OpenUrlRequest, OperationCapability, PickOpenFilesCapability, PickOpenFilesError,
239 PickOpenFilesRequest, PickOpenFilesResult, PickedFile, OPEN_URL, PICK_OPEN_FILES,
240 };
241 pub use crate::context::{
242 BarcodeScannerEffects, BiometricEffects, BluetoothEffects, CameraEffects, ClipboardEffects,
243 Effects, GeolocationEffects, HapticEffects, MicrophoneEffects, NfcEffects,
244 NotificationEffects, PasskeyEffects, ReducerContext, VolumeEffects, WifiEffects,
245 }; pub use crate::data_stream::{
247 collect_data_stream, empty_data_stream, single_chunk_data_stream, BoxFissionDataStream,
248 DataStreamId, DataStreamRegistry, FissionDataStream, FissionDataStreamError,
249 FissionDataStreamErrorKind,
250 };
251 pub use crate::effect::{
252 ActionInput, ActionInputCodecError, Effect, EffectEnvelope, RuntimeEffect, ScrollAlignment,
253 ScrollAxis, ScrollBehavior, ScrollIntoViewRequest,
254 };
255 pub use crate::env::{
256 Clipboard, DragSessionPayload, DragSessionState, Env, ImeHandler, InteractionStateMap,
257 RuntimeState, ScrollStateMap, WindowEnv, WindowTitle,
258 };
259 pub use crate::runtime::Runtime;
260 pub use crate::state::{LocalStateKey, LocalStateStore, StateField};
261 pub use bytes::Bytes;
262
263 pub use crate::build::{BuildCtxHandle, ViewHandle};
264 pub use crate::event::{
265 ExternalDragEvent, InputEvent, KeyCode, KeyEvent, LifecycleEvent, PointerButton,
266 PointerEvent, PointerId, PointerKind, PointerPhase, ScrollDeltaMode,
267 };
268 pub use crate::input::canvas::{
269 CanvasInteraction, CanvasInteractionKind, CanvasInteractionPhase,
270 };
271 pub use crate::input::viewport::{
272 ViewportInputKind, ViewportInteraction, ViewportInteractionPhase, ViewportStateMap,
273 };
274 pub use crate::motion::*;
275 pub use crate::platform::{
276 CancelAllNotificationsCapability, CancelNotificationCapability, CancelNotificationRequest,
277 DeepLink, DeepLinkConfig, DeepLinkReceived, DeepLinkSource,
278 GetNotificationSettingsCapability, NotificationActionButton, NotificationError,
279 NotificationId, NotificationPermission, NotificationPermissionRequest, NotificationReceipt,
280 NotificationRequest, NotificationResponse, NotificationResponseReceived,
281 NotificationSchedule, NotificationSettings, NotificationSound, PushPlatform,
282 PushRegistration, PushRegistrationRequest, RegisterPushNotificationsCapability,
283 RequestNotificationPermissionCapability, ScheduleNotificationCapability,
284 SetBadgeCountCapability, SetBadgeCountRequest, ShowNotificationCapability,
285 UnregisterPushNotificationsCapability, CANCEL_ALL_NOTIFICATIONS, CANCEL_NOTIFICATION,
286 GET_NOTIFICATION_SETTINGS, REGISTER_PUSH_NOTIFICATIONS, REQUEST_NOTIFICATION_PERMISSION,
287 SCHEDULE_NOTIFICATION, SET_BADGE_COUNT, SHOW_NOTIFICATION, UNREGISTER_PUSH_NOTIFICATIONS,
288 };
289 pub use crate::platform_barcode::{
290 BarcodeFormat, BarcodeImageDecodeRequest, BarcodePoint, BarcodeScanRequest,
291 BarcodeScanResult, BarcodeScanResults, BarcodeScannerError, CancelBarcodeScanCapability,
292 DecodeBarcodeImageCapability, ScanBarcodeCapability, CANCEL_BARCODE_SCAN,
293 DECODE_BARCODE_IMAGE, SCAN_BARCODE,
294 };
295 pub use crate::platform_biometric::{
296 AuthenticateBiometricCapability, BiometricAuthenticateRequest, BiometricAuthenticateResult,
297 BiometricAvailability, BiometricError, BiometricKind, BiometricStrength,
298 CancelBiometricAuthenticationCapability, GetBiometricAvailabilityCapability,
299 AUTHENTICATE_BIOMETRIC, CANCEL_BIOMETRIC_AUTHENTICATION, GET_BIOMETRIC_AVAILABILITY,
300 };
301 pub use crate::platform_bluetooth::{
302 BluetoothAdvertiseReceipt, BluetoothAdvertiseRequest, BluetoothAvailability,
303 BluetoothConnectRequest, BluetoothConnection, BluetoothDevice, BluetoothDisconnectRequest,
304 BluetoothError, BluetoothMode, BluetoothPermission, BluetoothPermissionRequest,
305 BluetoothReadRequest, BluetoothReadResult, BluetoothScanRequest, BluetoothScanResult,
306 BluetoothStopAdvertiseRequest, BluetoothWriteRequest, ConnectBluetoothDeviceCapability,
307 DisconnectBluetoothDeviceCapability, GetBluetoothAvailabilityCapability,
308 ReadBluetoothCharacteristicCapability, RequestBluetoothPermissionCapability,
309 ScanBluetoothDevicesCapability, StartBluetoothAdvertisingCapability,
310 StopBluetoothAdvertisingCapability, WriteBluetoothCharacteristicCapability,
311 CONNECT_BLUETOOTH_DEVICE, DISCONNECT_BLUETOOTH_DEVICE, GET_BLUETOOTH_AVAILABILITY,
312 READ_BLUETOOTH_CHARACTERISTIC, REQUEST_BLUETOOTH_PERMISSION, SCAN_BLUETOOTH_DEVICES,
313 START_BLUETOOTH_ADVERTISING, STOP_BLUETOOTH_ADVERTISING, WRITE_BLUETOOTH_CHARACTERISTIC,
314 };
315 pub use crate::platform_camera::{
316 CameraAvailability, CameraCapture, CameraCaptureRequest, CameraDevice, CameraError,
317 CameraFacing, CameraFlashMode, CameraFlashlightRequest, CameraImageFormat,
318 CameraPermission, CameraPermissionRequest, CameraResolution, CancelCameraCaptureCapability,
319 CapturePhotoCapability, GetCameraAvailabilityCapability, RequestCameraPermissionCapability,
320 SetCameraFlashlightCapability, CANCEL_CAMERA_CAPTURE, CAPTURE_PHOTO,
321 GET_CAMERA_AVAILABILITY, REQUEST_CAMERA_PERMISSION, SET_CAMERA_FLASHLIGHT,
322 };
323 pub use crate::platform_clipboard::{
324 ClearClipboardCapability, ClipboardContent, ClipboardError, ClipboardItem, ClipboardText,
325 ClipboardWriteTextRequest, ReadClipboardContentCapability, ReadClipboardTextCapability,
326 WriteClipboardContentCapability, WriteClipboardTextCapability, CLEAR_CLIPBOARD,
327 READ_CLIPBOARD_CONTENT, READ_CLIPBOARD_TEXT, WRITE_CLIPBOARD_CONTENT, WRITE_CLIPBOARD_TEXT,
328 };
329 pub use crate::platform_geolocation::{
330 GeolocationError, GeolocationPermission, GeolocationPermissionRequest, GeolocationPosition,
331 GeolocationPositionRequest, GetCurrentPositionCapability,
332 GetGeolocationPermissionCapability, RequestGeolocationPermissionCapability,
333 GET_CURRENT_POSITION, GET_GEOLOCATION_PERMISSION, REQUEST_GEOLOCATION_PERMISSION,
334 };
335 pub use crate::platform_haptics::{
336 HapticError, HapticImpactCapability, HapticImpactRequest, HapticImpactStyle,
337 HapticNotificationCapability, HapticNotificationKind, HapticNotificationRequest,
338 HapticPatternCapability, HapticPatternRequest, HapticPatternStep,
339 HapticSelectionCapability, HAPTIC_IMPACT, HAPTIC_NOTIFICATION, HAPTIC_PATTERN,
340 HAPTIC_SELECTION,
341 };
342 pub use crate::platform_microphone::{
343 AudioSampleFormat, CancelMicrophoneCaptureCapability, CaptureMicrophoneAudioCapability,
344 GetMicrophoneAvailabilityCapability, MicrophoneAvailability, MicrophoneCapture,
345 MicrophoneCaptureRequest, MicrophoneDevice, MicrophoneError, MicrophonePermission,
346 MicrophonePermissionRequest, RequestMicrophonePermissionCapability,
347 CANCEL_MICROPHONE_CAPTURE, CAPTURE_MICROPHONE_AUDIO, GET_MICROPHONE_AVAILABILITY,
348 REQUEST_MICROPHONE_PERMISSION,
349 };
350 pub use crate::platform_nfc::{
351 CancelNfcSessionCapability, EmulateNfcTagCapability, GetNfcAvailabilityCapability,
352 NfcAvailability, NfcEmulationRequest, NfcError, NfcRecord, NfcRecordTypeNameFormat,
353 NfcScanRequest, NfcSessionReceipt, NfcTag, NfcTagDiscovered, NfcTechnology,
354 NfcWriteRequest, ScanNfcTagCapability, WriteNfcTagCapability, CANCEL_NFC_SESSION,
355 EMULATE_NFC_TAG, GET_NFC_AVAILABILITY, SCAN_NFC_TAG, WRITE_NFC_TAG,
356 };
357 pub use crate::platform_passkey::{
358 AuthenticatePasskeyCapability, CancelPasskeyOperationCapability,
359 GetPasskeyAvailabilityCapability, PasskeyAlgorithm, PasskeyAttestationConveyance,
360 PasskeyAuthenticationRequest, PasskeyAuthenticationResult, PasskeyAuthenticatorAttachment,
361 PasskeyAuthenticatorSelection, PasskeyAvailability, PasskeyCredentialDescriptor,
362 PasskeyError, PasskeyMediation, PasskeyRegistrationRequest, PasskeyRegistrationResult,
363 PasskeyRelyingParty, PasskeyResidentKeyRequirement, PasskeyTransport, PasskeyUser,
364 PasskeyUserVerification, RegisterPasskeyCapability, AUTHENTICATE_PASSKEY,
365 CANCEL_PASSKEY_OPERATION, GET_PASSKEY_AVAILABILITY, REGISTER_PASSKEY,
366 };
367 pub use crate::platform_volume::{
368 AdjustVolumeLevelCapability, GetVolumeLevelCapability, SetVolumeLevelCapability,
369 VolumeAdjustDirection, VolumeAdjustRequest, VolumeError, VolumeLevel, VolumeSetRequest,
370 VolumeStream, ADJUST_VOLUME_LEVEL, GET_VOLUME_LEVEL, SET_VOLUME_LEVEL,
371 };
372 pub use crate::platform_wifi::{
373 ConnectWifiNetworkCapability, DisconnectWifiNetworkCapability,
374 GetWifiAvailabilityCapability, RequestWifiPermissionCapability, ScanWifiNetworksCapability,
375 WifiAvailability, WifiConnectRequest, WifiConnection, WifiDisconnectRequest, WifiError,
376 WifiNetwork, WifiPermission, WifiPermissionRequest, WifiScanRequest, WifiScanResult,
377 WifiSecurity, CONNECT_WIFI_NETWORK, DISCONNECT_WIFI_NETWORK, GET_WIFI_AVAILABILITY,
378 REQUEST_WIFI_PERMISSION, SCAN_WIFI_NETWORKS,
379 };
380 pub use crate::registry::{
381 ActionRegistry, Handler, JobResource, PortalLayer, ResourceKey, ResourcePolicy,
382 ResourceRegistry, RuntimeResourceDeclaration, RuntimeResourceKind, ServiceResource,
383 TimerResource, VideoRegistration,
384 };
385 pub use crate::scoped_action_handlers::ScopedActionResolution;
386 pub use crate::time::{Clock, CurrentTime};
387 pub use crate::ui::{
388 provider, ActionScope, BadgeTone, Button, ButtonHierarchy, ButtonMotion, CardPattern,
389 Column, ComponentSize, ComponentState, CustomWidget, IosAudioSessionCategory,
390 IosAudioSessionCategoryOption, IosAudioSessionMode, IosVideoAudioOptions, Pressable,
391 PressableRole, PressableStyle, Provider, Responsive, ResponsiveCase, ResponsiveQuery, Row,
392 Text, Video, VideoAudioActivation, VideoAudioOptions, VideoAudioPolicy, VideoSource,
393 Widget, WidgetIdExt, WidgetKind,
394 };
395 pub use crate::view::{ComputedView, FissionViewField, Selector, ValueView, View};
396 pub use crate::{
397 reduce, reduce_with, video_asset, video_file, video_network, widgets, with_reducer,
398 };
399 pub use fission_ir::op;
400 pub use fission_ir::op::{
401 BoxAlignment, BoxGridPlacement, BoxPosition, BoxStyle, GridPlacement, GridTrack, Length,
402 Overflow,
403 };
404 pub use fission_ir::{EmbedKind, FocusPolicy, Op, Role, Semantics, WidgetId};
405 pub use fission_layout::{
406 BoxConstraints, FlexDirection, LayoutEngine, LayoutInspection, LayoutNodeGeometry,
407 LayoutOp, LayoutPoint, LayoutRect, LayoutSize, LayoutSnapshot, LayoutUnit, TextMeasurer,
408 };
409}
410
411#[cfg(test)]
412mod tests;
413
414pub use action::{
415 Action, ActionEnvelope, ActionId, ActionScopeId, GlobalState, ShellRouteChanged,
416 UpdateTextInput,
417};
418pub use async_runtime::{
419 BoxFuture, JobCtx, JobRef, JobSpec, ResourceExecutionContext, ServiceBindings, ServiceCtx,
420 ServiceRunner, ServiceSlot, ServiceSpec, ServiceType,
421};
422pub use bytes::Bytes;
423pub use capability::{
424 CapabilityCtx, CapabilityInvocationPayload, CapabilityType, OpenUrlCapability, OpenUrlRequest,
425 OperationCapability, PickOpenFilesCapability, PickOpenFilesError, PickOpenFilesRequest,
426 PickOpenFilesResult, PickedFile, OPEN_URL, PICK_OPEN_FILES,
427};
428pub use context::{
429 BarcodeScannerEffects, BiometricEffects, BluetoothEffects, CameraEffects, ClipboardEffects,
430 Effects, GeolocationEffects, HapticEffects, MicrophoneEffects, NfcEffects, NotificationEffects,
431 PasskeyEffects, ReducerContext, VolumeEffects, WifiEffects,
432}; pub use data_stream::{
434 collect_data_stream, empty_data_stream, single_chunk_data_stream, BoxFissionDataStream,
435 DataStreamId, DataStreamRegistry, FissionDataStream, FissionDataStreamError,
436 FissionDataStreamErrorKind,
437};
438pub use effect::{
439 ActionInput, ActionInputCodecError, Effect, EffectEnvelope, RuntimeEffect, ScrollAlignment,
440 ScrollAxis, ScrollBehavior, ScrollIntoViewRequest,
441};
442pub use env::{
443 Clipboard, DragSessionPayload, DragSessionState, Env, ImeHandler, InteractionStateMap,
444 RouteLocation, RuntimeState, ScrollStateMap, WindowEnv, WindowTitle,
445};
446pub use motion::*;
447pub use runtime::Runtime;
448pub use state::{LocalStateKey, LocalStateStore, StateField};
449
450pub use build::{BuildCtxHandle, ViewHandle};
451pub use event::{
452 ExternalDragEvent, InputEvent, KeyCode, KeyEvent, LifecycleEvent, PointerButton, PointerEvent,
453 PointerId, PointerKind, PointerPhase, ScrollDeltaMode,
454};
455pub use fission_ir::op;
456pub use fission_ir::op::{
457 BoxAlignment, BoxGridPlacement, BoxPosition, BoxStyle, GridPlacement, GridTrack, Length,
458 Overflow,
459};
460pub use fission_ir::{EmbedKind, FocusPolicy, Op, Role, Semantics, WidgetId};
461pub use fission_layout::{
462 BoxConstraints, FlexDirection, LayoutEngine, LayoutInspection, LayoutNodeGeometry, LayoutOp,
463 LayoutPoint, LayoutRect, LayoutSize, LayoutSnapshot, LayoutUnit, TextMeasurer,
464};
465pub use input::canvas::{CanvasInteraction, CanvasInteractionKind, CanvasInteractionPhase};
466pub use input::viewport::{
467 ViewportInputKind, ViewportInteraction, ViewportInteractionPhase, ViewportStateMap,
468};
469pub use platform::{
470 CancelAllNotificationsCapability, CancelNotificationCapability, CancelNotificationRequest,
471 DeepLink, DeepLinkConfig, DeepLinkReceived, DeepLinkSource, GetNotificationSettingsCapability,
472 NotificationActionButton, NotificationError, NotificationId, NotificationPermission,
473 NotificationPermissionRequest, NotificationReceipt, NotificationRequest, NotificationResponse,
474 NotificationResponseReceived, NotificationSchedule, NotificationSettings, NotificationSound,
475 PushPlatform, PushRegistration, PushRegistrationRequest, RegisterPushNotificationsCapability,
476 RequestNotificationPermissionCapability, ScheduleNotificationCapability,
477 SetBadgeCountCapability, SetBadgeCountRequest, ShowNotificationCapability,
478 UnregisterPushNotificationsCapability, CANCEL_ALL_NOTIFICATIONS, CANCEL_NOTIFICATION,
479 GET_NOTIFICATION_SETTINGS, REGISTER_PUSH_NOTIFICATIONS, REQUEST_NOTIFICATION_PERMISSION,
480 SCHEDULE_NOTIFICATION, SET_BADGE_COUNT, SHOW_NOTIFICATION, UNREGISTER_PUSH_NOTIFICATIONS,
481};
482pub use platform_barcode::{
483 BarcodeFormat, BarcodeImageDecodeRequest, BarcodePoint, BarcodeScanRequest, BarcodeScanResult,
484 BarcodeScanResults, BarcodeScannerError, CancelBarcodeScanCapability,
485 DecodeBarcodeImageCapability, ScanBarcodeCapability, CANCEL_BARCODE_SCAN, DECODE_BARCODE_IMAGE,
486 SCAN_BARCODE,
487};
488pub use platform_biometric::{
489 AuthenticateBiometricCapability, BiometricAuthenticateRequest, BiometricAuthenticateResult,
490 BiometricAvailability, BiometricError, BiometricKind, BiometricStrength,
491 CancelBiometricAuthenticationCapability, GetBiometricAvailabilityCapability,
492 AUTHENTICATE_BIOMETRIC, CANCEL_BIOMETRIC_AUTHENTICATION, GET_BIOMETRIC_AVAILABILITY,
493};
494pub use platform_bluetooth::{
495 BluetoothAdvertiseReceipt, BluetoothAdvertiseRequest, BluetoothAvailability,
496 BluetoothConnectRequest, BluetoothConnection, BluetoothDevice, BluetoothDisconnectRequest,
497 BluetoothError, BluetoothMode, BluetoothPermission, BluetoothPermissionRequest,
498 BluetoothReadRequest, BluetoothReadResult, BluetoothScanRequest, BluetoothScanResult,
499 BluetoothStopAdvertiseRequest, BluetoothWriteRequest, ConnectBluetoothDeviceCapability,
500 DisconnectBluetoothDeviceCapability, GetBluetoothAvailabilityCapability,
501 ReadBluetoothCharacteristicCapability, RequestBluetoothPermissionCapability,
502 ScanBluetoothDevicesCapability, StartBluetoothAdvertisingCapability,
503 StopBluetoothAdvertisingCapability, WriteBluetoothCharacteristicCapability,
504 CONNECT_BLUETOOTH_DEVICE, DISCONNECT_BLUETOOTH_DEVICE, GET_BLUETOOTH_AVAILABILITY,
505 READ_BLUETOOTH_CHARACTERISTIC, REQUEST_BLUETOOTH_PERMISSION, SCAN_BLUETOOTH_DEVICES,
506 START_BLUETOOTH_ADVERTISING, STOP_BLUETOOTH_ADVERTISING, WRITE_BLUETOOTH_CHARACTERISTIC,
507};
508pub use platform_camera::{
509 CameraAvailability, CameraCapture, CameraCaptureRequest, CameraDevice, CameraError,
510 CameraFacing, CameraFlashMode, CameraFlashlightRequest, CameraImageFormat, CameraPermission,
511 CameraPermissionRequest, CameraResolution, CancelCameraCaptureCapability,
512 CapturePhotoCapability, GetCameraAvailabilityCapability, RequestCameraPermissionCapability,
513 SetCameraFlashlightCapability, CANCEL_CAMERA_CAPTURE, CAPTURE_PHOTO, GET_CAMERA_AVAILABILITY,
514 REQUEST_CAMERA_PERMISSION, SET_CAMERA_FLASHLIGHT,
515};
516pub use platform_clipboard::{
517 ClearClipboardCapability, ClipboardContent, ClipboardError, ClipboardItem, ClipboardText,
518 ClipboardWriteTextRequest, ReadClipboardContentCapability, ReadClipboardTextCapability,
519 WriteClipboardContentCapability, WriteClipboardTextCapability, CLEAR_CLIPBOARD,
520 READ_CLIPBOARD_CONTENT, READ_CLIPBOARD_TEXT, WRITE_CLIPBOARD_CONTENT, WRITE_CLIPBOARD_TEXT,
521};
522pub use platform_geolocation::{
523 GeolocationError, GeolocationPermission, GeolocationPermissionRequest, GeolocationPosition,
524 GeolocationPositionRequest, GetCurrentPositionCapability, GetGeolocationPermissionCapability,
525 RequestGeolocationPermissionCapability, GET_CURRENT_POSITION, GET_GEOLOCATION_PERMISSION,
526 REQUEST_GEOLOCATION_PERMISSION,
527};
528pub use platform_haptics::{
529 HapticError, HapticImpactCapability, HapticImpactRequest, HapticImpactStyle,
530 HapticNotificationCapability, HapticNotificationKind, HapticNotificationRequest,
531 HapticPatternCapability, HapticPatternRequest, HapticPatternStep, HapticSelectionCapability,
532 HAPTIC_IMPACT, HAPTIC_NOTIFICATION, HAPTIC_PATTERN, HAPTIC_SELECTION,
533};
534pub use platform_microphone::{
535 AudioSampleFormat, CancelMicrophoneCaptureCapability, CaptureMicrophoneAudioCapability,
536 GetMicrophoneAvailabilityCapability, MicrophoneAvailability, MicrophoneCapture,
537 MicrophoneCaptureRequest, MicrophoneDevice, MicrophoneError, MicrophonePermission,
538 MicrophonePermissionRequest, RequestMicrophonePermissionCapability, CANCEL_MICROPHONE_CAPTURE,
539 CAPTURE_MICROPHONE_AUDIO, GET_MICROPHONE_AVAILABILITY, REQUEST_MICROPHONE_PERMISSION,
540};
541pub use platform_nfc::{
542 CancelNfcSessionCapability, EmulateNfcTagCapability, GetNfcAvailabilityCapability,
543 NfcAvailability, NfcEmulationRequest, NfcError, NfcRecord, NfcRecordTypeNameFormat,
544 NfcScanRequest, NfcSessionReceipt, NfcTag, NfcTagDiscovered, NfcTechnology, NfcWriteRequest,
545 ScanNfcTagCapability, WriteNfcTagCapability, CANCEL_NFC_SESSION, EMULATE_NFC_TAG,
546 GET_NFC_AVAILABILITY, SCAN_NFC_TAG, WRITE_NFC_TAG,
547};
548pub use platform_passkey::{
549 AuthenticatePasskeyCapability, CancelPasskeyOperationCapability,
550 GetPasskeyAvailabilityCapability, PasskeyAlgorithm, PasskeyAttestationConveyance,
551 PasskeyAuthenticationRequest, PasskeyAuthenticationResult, PasskeyAuthenticatorAttachment,
552 PasskeyAuthenticatorSelection, PasskeyAvailability, PasskeyCredentialDescriptor, PasskeyError,
553 PasskeyMediation, PasskeyRegistrationRequest, PasskeyRegistrationResult, PasskeyRelyingParty,
554 PasskeyResidentKeyRequirement, PasskeyTransport, PasskeyUser, PasskeyUserVerification,
555 RegisterPasskeyCapability, AUTHENTICATE_PASSKEY, CANCEL_PASSKEY_OPERATION,
556 GET_PASSKEY_AVAILABILITY, REGISTER_PASSKEY,
557};
558pub use platform_volume::{
559 AdjustVolumeLevelCapability, GetVolumeLevelCapability, SetVolumeLevelCapability,
560 VolumeAdjustDirection, VolumeAdjustRequest, VolumeError, VolumeLevel, VolumeSetRequest,
561 VolumeStream, ADJUST_VOLUME_LEVEL, GET_VOLUME_LEVEL, SET_VOLUME_LEVEL,
562};
563pub use platform_wifi::{
564 ConnectWifiNetworkCapability, DisconnectWifiNetworkCapability, GetWifiAvailabilityCapability,
565 RequestWifiPermissionCapability, ScanWifiNetworksCapability, WifiAvailability,
566 WifiConnectRequest, WifiConnection, WifiDisconnectRequest, WifiError, WifiNetwork,
567 WifiPermission, WifiPermissionRequest, WifiScanRequest, WifiScanResult, WifiSecurity,
568 CONNECT_WIFI_NETWORK, DISCONNECT_WIFI_NETWORK, GET_WIFI_AVAILABILITY, REQUEST_WIFI_PERMISSION,
569 SCAN_WIFI_NETWORKS,
570};
571pub use registry::{
572 ActionRegistry, Handler, JobResource, PortalLayer, ResourceKey, ResourcePolicy,
573 ResourceRegistry, RuntimeResourceDeclaration, RuntimeResourceKind, ServiceResource,
574 TimerResource, VideoRegistration,
575};
576pub use scoped_action_handlers::ScopedActionResolution;
577pub use time::{Clock, CurrentTime};
578pub use ui::{
579 provider, ActionScope, BadgeTone, Button, ButtonHierarchy, ButtonMotion, CardPattern, Column,
580 ComponentSize, ComponentState, CustomWidget, IosAudioSessionCategory,
581 IosAudioSessionCategoryOption, IosAudioSessionMode, IosVideoAudioOptions, Pressable,
582 PressableRole, PressableStyle, Provider, Responsive, ResponsiveCase, ResponsiveQuery, Row,
583 Text, Video, VideoAudioActivation, VideoAudioOptions, VideoAudioPolicy, VideoSource, Widget,
584 WidgetIdExt, WidgetKind,
585};
586pub use view::{ComputedView, FissionViewField, Selector, ValueView, View};
587
588#[macro_export]
598macro_rules! reduce_with {
599 ($handler:expr $(,)?) => {
600 $handler as $crate::Handler<_, _>
601 };
602}
603
604#[macro_export]
606macro_rules! reduce {
607 ($handler:expr $(,)?) => {
608 $crate::reduce_with!($handler)
609 };
610}
611
612#[macro_export]
620macro_rules! widgets {
621 ($($widget:expr),* $(,)?) => {
622 {
623 let mut widgets = ::std::vec::Vec::<$crate::Widget>::new();
624 let collection_scope = $crate::build::collection_scope(file!(), line!(), column!());
625 $(
626 let child_index = widgets.len() as u32;
627 let child_scope = $crate::WidgetId::derived(
628 collection_scope.as_u128(),
629 &[child_index],
630 );
631 widgets.push($crate::build::with_implicit_widget_id(child_scope, || {
632 $crate::Widget::from($widget)
633 }));
634 )*
635 widgets
636 }
637 };
638}
639
640#[macro_export]
646macro_rules! video_asset {
647 ($path:literal $(,)?) => {{
648 const _: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/", $path));
649 $crate::ui::Video::asset($path)
650 }};
651}
652
653#[macro_export]
659macro_rules! video_file {
660 ($path:expr $(,)?) => {{
661 const _: &[u8] = include_bytes!($path);
662 $crate::ui::Video::file($path)
663 }};
664}
665
666#[macro_export]
672macro_rules! video_network {
673 ($url:literal $(,)?) => {{
674 $crate::ui::Video::network($url)
675 }};
676}
677
678#[macro_export]
686macro_rules! with_reducer {
687 ($ctx:expr, $action:expr, $handler:expr $(,)?) => {
688 $ctx.bind($action, $crate::reduce_with!($handler))
689 };
690}
691
692#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
704pub struct Tick {
705 pub dt: CurrentTime,
707}
708
709impl Action for Tick {
710 fn static_id() -> ActionId {
711 *TICK_ACTION_ID
712 }
713}
714
715lazy_static! {
716 pub static ref TICK_ACTION_ID: ActionId = ActionId::from_name("fission_core::Tick");
717}
718
719#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
731pub struct AdvanceTo {
732 pub time: CurrentTime,
734}
735
736impl Action for AdvanceTo {
737 fn static_id() -> ActionId {
738 *ADVANCE_TO_ACTION_ID
739 }
740}
741
742lazy_static! {
743 pub static ref ADVANCE_TO_ACTION_ID: ActionId = ActionId::from_name("fission_core::AdvanceTo");
744}
745
746pub(crate) type BoxedReducer = Box<
751 dyn FnMut(
752 &mut HashMap<TypeId, Box<dyn GlobalState>>,
753 &ActionEnvelope,
754 WidgetId,
755 &mut Vec<EffectEnvelope>,
756 &ActionInput,
757 &Arc<EffectCallbackRegistry>,
758 ) -> Result<()>
759 + Send
760 + Sync,
761>;
762
763pub(crate) struct EffectCallbackRegistry {
768 reducers: Mutex<HashMap<ActionId, Vec<BoxedReducer>>>,
769}
770
771impl EffectCallbackRegistry {
772 pub(crate) fn new() -> Self {
773 Self {
774 reducers: Mutex::new(HashMap::new()),
775 }
776 }
777
778 pub(crate) fn register(&self, action_id: ActionId, reducer: BoxedReducer) {
779 self.reducers
780 .lock()
781 .unwrap_or_else(std::sync::PoisonError::into_inner)
782 .entry(action_id)
783 .or_default()
784 .push(reducer);
785 }
786
787 pub(crate) fn take(&self, action_id: ActionId) -> Vec<BoxedReducer> {
788 self.reducers
789 .lock()
790 .unwrap_or_else(std::sync::PoisonError::into_inner)
791 .remove(&action_id)
792 .unwrap_or_default()
793 }
794
795 pub(crate) fn clear(&self) -> usize {
796 let mut reducers = self
797 .reducers
798 .lock()
799 .unwrap_or_else(std::sync::PoisonError::into_inner);
800 let callback_count = reducers.values().map(Vec::len).sum();
801 reducers.clear();
802 callback_count
803 }
804}