Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-ui-core/src/core/entity.rs
StratoSDK / crates / strato-ui-core / src / core / entity.rs
1use core::fmt;
2use std::sync::atomic::{AtomicUsize, Ordering};
3 
4use serde::{Deserialize, Serialize};
5 
6use crate::ModelHandle;
7 
8/// A unique identifier for a View or a Model.
9///
10/// View and Model identifiers are not separately namespaced because we want to
11/// use them interchangeably in several places, e.g. in observations.
12#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
13pub struct EntityId(usize);
14 
15impl EntityId {
16 /// Constructs a new globally-unique entity ID.
17 #[allow(clippy::new_without_default)]
18 pub fn new() -> EntityId {
19 static NEXT_ID: AtomicUsize = AtomicUsize::new(0);
20 let raw = NEXT_ID.fetch_add(1, Ordering::Relaxed);
21 EntityId(raw)
22 }
23 
24 pub fn from_usize(value: usize) -> EntityId {
25 EntityId(value)
26 }
27}
28 
29impl fmt::Display for EntityId {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 std::fmt::Display::fmt(&self.0, f)
32 }
33}
34 
35/// An interface for a structure that can produce events.
36///
37/// TODO(vorporeal): This can probably be eliminated entirely, with View and
38/// Model exposing the associated type Event independently.
39pub trait Entity: 'static {
40 type Event;
41}
42 
43/// An interface for a structure holding global state for the application.
44pub trait SingletonEntity: Entity + Sized {
45 /// Returns the handle to the single model of this type stored within the
46 /// provided application state.
47 fn handle<T: GetSingletonModelHandle>(ctx: &T) -> ModelHandle<Self> {
48 ctx.get_singleton_model_handle()
49 }
50 
51 fn as_ref(ctx: &crate::AppContext) -> &Self {
52 ctx.get_singleton_model_as_ref()
53 }
54}
55 
56/// A trait for retrieving a handle to a singleton model by type.
57pub trait GetSingletonModelHandle {
58 /// Returns the handle to the single model of this type stored within the
59 /// provided application state.
60 fn get_singleton_model_handle<T: SingletonEntity>(&self) -> ModelHandle<T>;
61}
62 
63pub trait AddSingletonModel {
64 fn add_singleton_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
65 where
66 T: SingletonEntity,
67 F: FnOnce(&mut super::ModelContext<T>) -> T;
68}
69