1#![deny(missing_docs)]
2#![doc = include_str!("../README.md")]
3#![deny(unsafe_code)]
4
5pub extern crate self as cranpose_core;
6
7mod applier;
8mod applier_host;
9pub use applier::Applier;
10mod blocking;
11mod bubble_passes;
12mod callbacks;
13mod child_positions;
14mod child_sync;
15pub(crate) use child_positions::{
16 build_child_positions, insert_child_into_diff_state, move_child_in_diff_state,
17};
18pub(crate) use child_sync::{
19 apply_remove_child, attach_child_at, cleanup_detached_child, detach_child_from_parent,
20 insert_child_with_reparenting, remove_child_and_cleanup_now, sync_or_settle_children,
21};
22mod command;
23pub(crate) use command::{
24 Command, CommandCallback, DeferredChildCleanup, DeferredChildCleanupQueue, DirtyBubble,
25};
26mod command_queue;
27pub(crate) use command_queue::{
28 COMMAND_FLUSH_THRESHOLD, ChildList, CommandQueue, SMALL_CHILD_SYNC_LINEAR_THRESHOLD,
29};
30#[cfg(test)]
31pub(crate) use command_queue::{CommandTag, SyncChildrenCommand};
32mod composer;
33pub mod composer_context;
36pub(crate) use composer_context::with_current_composer_opt;
37pub use composer_context::{
38 current_recompose_scope_invalidated_only_by, recompose_current_scope_again, withCurrentComposer,
39};
40mod composition;
41mod composition_locals;
42pub(crate) use composition_locals::{LocalKey, LocalStackSnapshot};
43mod computed_state;
44pub mod concurrency;
45mod debug_trace;
46mod disposable_effect;
47pub use diagnostics::{DIAGNOSTICS, Diagnostic, Diagnostics};
48#[cfg(test)]
49pub(crate) use disposable_effect::DisposableEffectState;
50pub use disposable_effect::{
51 __disposable_effect_impl, DisposableEffect, DisposableEffectResult, DisposableEffectScope,
52 SideEffect,
53};
54mod effect_key;
55mod emit;
56mod event_dispatch;
57pub use event_dispatch::{
58 EventHandlerScopeGuard, dispatch_ui_event, enter_event_handler_scope, in_applied_snapshot,
59 in_event_handler, run_in_mutable_snapshot,
60};
61pub mod debug_toggles;
62pub mod diagnostics;
63#[cfg(any(feature = "internal", test))]
64mod frame_clock;
65mod hooks;
66#[cfg(feature = "internal")]
67mod node_reads;
68pub(crate) use key_group::{explicit_group_key_seed, hash_key};
69mod key_group;
70pub use key_group::{key, with_key};
71mod launched_effect;
72mod layout_dirt_roots;
73mod location_key;
74mod memory_applier;
75mod worker_job;
76#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
77mod worker_pool;
78pub use memory_applier::{MemoryApplier, MemoryApplierDebugStats, SceneNodeAttachmentScratch};
79mod movable_content;
80mod node;
81#[cfg(any(test, debug_assertions))]
82pub(crate) use location_key::LocationKeyDebugInfo;
83pub(crate) use location_key::{HotOrigin, avalanche_location_key};
84#[cfg(test)]
85pub(crate) use location_key::{
86 hot_call_site_key, location_key_debug_collision_count_for_test,
87 location_key_debug_info_for_test, register_location_key_debug_info_for_test,
88};
89pub use movable_content::{
90 MovableContent, forget_movable, movable, movableContentOf, rememberMovableContentOf,
91};
92pub use node::{
93 Node, bubble_layout_dirty, bubble_layout_dirty_in_composer, bubble_measure_dirty,
94 bubble_measure_dirty_in_composer, bubble_semantics_dirty, bubble_semantics_dirty_in_composer,
95 pop_parent, push_parent, queue_semantics_invalidation, with_node_mut,
96};
97mod node_error;
98mod node_id_cell;
99pub use node_id_cell::NodeIdCell;
100mod node_marks;
101mod phase;
102pub use phase::Phase;
103mod anchor_id;
104pub use anchor_id::AnchorId;
105mod packed_u64;
106pub use node_error::NodeError;
107pub use packed_u64::PackedU64;
108mod process_ids;
109pub use process_ids::ProcessIds;
110pub mod owned;
112mod pausable;
113#[doc(hidden)]
114pub use pausable::{PausableContent, with_pausable_content};
115pub mod platform;
116mod recompose;
117mod recompose_scope;
118pub(crate) use recompose_scope::{BodyRun, RecomposeScopeInner, ScopeRead};
119pub use recompose_scope::{RecomposeOptions, RecomposeScope, RecomposeScopeRegistryDebugStats};
120mod recycle_pool;
121mod recycled_node;
122use recycle_pool::RecyclePool;
123pub use recycled_node::{RecycleOrigin, RecycledNode, RecycledNodeInsertion};
124mod retention;
125pub mod runtime;
128mod runtime_cell;
129#[cfg(test)]
130pub(crate) use runtime::{TestRuntime, TestScheduler};
131#[expect(clippy::multiple_inherent_impl, reason = "one file per concern")]
132mod slot;
133mod slots_host;
134pub(crate) use slots_host::SlotPassOutcome;
135pub use slots_host::SlotsHost;
136pub mod snapshot_double_index_heap;
138pub mod snapshot_id_set;
140pub mod snapshot_pinning;
142pub mod snapshot_state_observer;
144pub mod snapshot_v2;
145mod snapshot_weak_set;
146pub mod source_trace;
147mod stable_index;
148mod state;
149#[doc(hidden)]
150pub use source_trace::{__inline_source_scope, __source_scope};
151#[doc(hidden)]
152pub use thread_state::with_or_fresh;
153mod stage_times;
154pub mod subcompose;
155mod task_site;
156pub use task_site::TaskSite;
157mod thread_state;
158#[doc(hidden)]
159pub use stage_times::{StageTimes, stage_ms};
160
161#[cfg(feature = "internal")]
162#[doc(hidden)]
163pub mod internal {
164 pub use crate::{
165 frame_clock::{FrameCallbackRegistration, FrameClock},
166 node_reads::{NodeReads, ReaderGuard},
167 };
168}
169pub use applier_host::{ApplierGuard, ApplierHost, ConcreteApplierHost, NodeDisposal};
170pub use blocking::{
171 BlockingError, BlockingExecutor, BlockingExecutorConfig, BlockingTask, BlockingWork,
172 launchBlocking, withBlocking,
173};
174pub use callbacks::{
175 CallbackForwarder, CallbackHolder, ParamReturnState, ParamSlot, ParamState, ReturnSlot,
176 SharedParam, refresh_param, refresh_shared_param, store_param,
177};
178pub use composer::{
179 __branch_group_scope_advance, __branch_group_scope_deferred, BranchGroupGuard,
180 CapturedCompositionContext, ComposableGroup, Composer, ParameterChange, ScopedBranchGroupGuard,
181 ValueSlotHandle,
182};
183pub(crate) use composer::{ComposerCore, EmittedNode, ParentAttachMode, ParentFrame};
184#[cfg(any(test, feature = "leak-debug"))]
185pub use composition::CompositionPassDebugStats;
186pub use composition::{Composition, LayoutBudget, ROOT_RENDER_REPLAY_LIMIT};
187pub use composition_locals::{
188 CompositionLocal, CompositionLocalAccessorScope, CompositionLocalProvider, ProvidedValue,
189 ReadableCompositionLocal, StaticCompositionLocal, compositionLocalOf,
190 compositionLocalOfWithPolicy, compositionLocalWithComputedDefaultOf, staticCompositionLocalOf,
191 staticCompositionLocalOfWithPolicy, staticCompositionLocalWithComputedDefaultOf,
192};
193pub(crate) use composition_locals::{ComputedLocalEntry, LocalStateEntry};
194#[doc(hidden)]
195pub use computed_state::{ComputedState, computedStateOf};
196pub use concurrency::{
197 CollectEvents, CoroutineScope, Delay, EventChannel, EventSender, EventStream, EventStreamNext,
198 ProduceScope, collectAsState, delay, interval, produceState, rememberCoroutineScope,
199 rememberEventStream, spawn_ui_task,
200};
201#[doc(hidden)]
202pub use debug_trace::{
203 debug_label_current_scope, debug_live_recompose_scope_count,
204 debug_recompose_scope_registry_stats, debug_scope_invalidation_sources, debug_scope_label,
205};
206pub use hooks::{
207 derivedStateOf, mutableStateList, mutableStateListOf, mutableStateMap, mutableStateMapOf,
208 mutableStateOf, mutableStateOfNeverEqual, ownedMutableStateOf, ownedMutableStateOfNeverEqual,
209 remember, rememberKeyed, rememberMutableStateOf, rememberMutableStateOfNeverEqual,
210 rememberUpdatedState, try_mutableStateOf,
211};
212pub use launched_effect::{
213 __launched_effect_impl, CancelToken, LaunchedEffect, LaunchedEffectScope,
214};
215pub use location_key::{
216 __constant, HotOriginGuard, branch_location_key, cached_composable_definition_key,
217 caller_location_key, composable_definition_key, composable_identity_key, const_location_key,
218 constant_value_key, hot_branch_key, hot_definition_key, hot_origin, location_key,
219 noted_location_key,
220};
221pub use node_marks::NodeMarks;
222pub use owned::Owned;
223pub use platform::{Clock, RuntimeScheduler, SchedulerRef, scheduler_ref};
224pub use retention::{RetentionBudget, RetentionEvictionPolicy, RetentionMode, RetentionPolicy};
225#[doc(hidden)]
226pub use runtime::{
227 DefaultScheduler, Runtime, RuntimeHandle, StateId, TaskHandle, UiDispatcher,
228 current_runtime_handle, schedule_frame, schedule_node_update,
229};
230pub use runtime_cell::RuntimeCell;
231#[cfg(any(test, feature = "leak-debug"))]
232pub use slot::SlotTableMutationDebugStats;
233pub use slot::{
234 SlotDebugAnchor, SlotDebugEntry, SlotDebugEntryKind, SlotDebugGroup, SlotDebugScope,
235 SlotDebugSnapshot, SlotRetentionDebugStats, SlotTable, SlotTableDebugStats,
236 SlotTableLocalDebugStats,
237};
238pub use snapshot_state_observer::SnapshotStateObserver;
239pub use worker_job::{__worker, WorkerCall, WorkerData, WorkerJob};
240
241#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
244#[cfg_attr(target_os = "espidf", repr(C, packed(4)))]
245pub struct Key(pub u64);
246
247impl Key {
248 pub const fn scoped(self, site: Self) -> Self {
250 Self(self.0 ^ site.0)
251 }
252
253 pub(crate) const fn mixed(self, other: Self) -> Self {
255 Self((self.0 ^ other.0).wrapping_mul(0x0000_0100_0000_01b3))
256 }
257}
258
259impl std::fmt::Display for Key {
260 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
261 { self.0 }.fmt(f)
262 }
263}
264#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
266pub struct NodeId(pub usize);
267
268impl NodeId {
269 pub(crate) const fn next(self) -> Self {
271 Self(self.0.saturating_add(1))
272 }
273}
274
275impl std::str::FromStr for NodeId {
276 type Err = std::num::ParseIntError;
277
278 fn from_str(text: &str) -> Result<Self, Self::Err> {
279 text.parse().map(Self)
280 }
281}
282
283impl std::fmt::Display for NodeId {
284 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
285 self.0.fmt(f)
286 }
287}
288
289pub(crate) type ScopeId = usize;
290pub(crate) type FrameCallbackId = u64;
291pub use composer_context::{
292 __current_composer, note_nested_slots_host, with_composer as with_current_composer,
293};
294pub(crate) use state::MutableStateInner;
295pub use state::{
296 MutableState, OwnedMutableState, SnapshotStateList, SnapshotStateMap, State,
297 StateSubscriptionHold,
298};
299pub use subcompose::{
300 ContentTypeReusePolicy, DefaultSlotReusePolicy, SlotId, SlotReusePolicy, SubcomposeState,
301 TypedSlot,
302};
303
304#[cfg(test)]
305#[path = "tests/mod.rs"]
306mod tests;
307
308#[cfg(test)]
309#[path = "tests/recursive_decrease_increase_test.rs"]
310mod recursive_decrease_increase_test;
311
312pub mod collections;
313pub mod hash;
315
316#[cfg(any(test, feature = "test-helpers"))]
319pub mod test_scratch;
320#[cfg(any(test, feature = "test-helpers"))]
321pub use test_scratch::test_scratch_dir;