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