session and seat management daemon
0

Configure Feed

Select the types of activity you want to include in your feed.

init world

authored by

r0chd and committed by
Tangled
(Jul 1, 2026, 1:17 AM +0300) a3dbca71 120a3235

+148 -1
+44
daemon/src/ecs/components.rs
··· 1 + use crate::{session_core_session, session_core_v1}; 2 + use std::time; 3 + 4 + pub trait Component: Sized { 5 + fn storage(world: &mut super::World) -> &mut Vec<Option<Self>>; 6 + fn storage_ref(world: &super::World) -> &Vec<Option<Self>>; 7 + } 8 + 9 + macro_rules! component { 10 + ($name:ident, $field:ident) => { 11 + impl Component for $name { 12 + fn storage(world: &mut super::World) -> &mut Vec<Option<Self>> { 13 + &mut world.$field 14 + } 15 + fn storage_ref(world: &super::World) -> &Vec<Option<Self>> { 16 + &world.$field 17 + } 18 + } 19 + }; 20 + } 21 + 22 + pub struct Uid(pub u32); 23 + component!(Uid, uid_components); 24 + 25 + pub struct Username(pub String); 26 + component!(Username, username_components); 27 + 28 + pub struct Vt(pub u32); 29 + component!(Vt, vt_components); 30 + 31 + pub struct Seat(pub Option<String>); 32 + component!(Seat, seat_components); 33 + 34 + pub struct Timestamp(pub time::SystemTime); 35 + component!(Timestamp, timestamp_components); 36 + 37 + pub struct LeaderId(pub i32); 38 + component!(LeaderId, leader_id_components); 39 + 40 + pub struct SessionObjects(pub Vec<session_core_session::SessionCoreSession>); 41 + component!(SessionObjects, session_objects_components); 42 + 43 + pub struct ActiveState(pub session_core_v1::ActiveState); 44 + component!(ActiveState, active_state_components);
+100
daemon/src/ecs/mod.rs
··· 1 + mod components; 2 + 3 + use crate::session; 4 + pub use components::*; 5 + use crate::{session_core_session, session_core_v1}; 6 + use std::collections::HashMap; 7 + use std::time; 8 + 9 + #[derive(Copy, Clone, Default)] 10 + pub struct Entity(usize); 11 + 12 + #[derive(Default)] 13 + pub struct World { 14 + next_entity: usize, 15 + free_entities: Vec<Entity>, 16 + session_entities: HashMap<session::SessionId, Entity>, 17 + uid_components: Vec<Option<Uid>>, 18 + username_components: Vec<Option<Username>>, 19 + vt_components: Vec<Option<Vt>>, 20 + seat_components: Vec<Option<Seat>>, 21 + timestamp_components: Vec<Option<Timestamp>>, 22 + leader_id_components: Vec<Option<LeaderId>>, 23 + session_objects_components: Vec<Option<SessionObjects>>, 24 + active_state_components: Vec<Option<ActiveState>>, 25 + } 26 + 27 + impl World { 28 + pub fn new() -> Self { 29 + Self::default() 30 + } 31 + 32 + fn entity(&mut self) -> Entity { 33 + if let Some(entity) = self.free_entities.pop() { 34 + return entity; 35 + } 36 + 37 + let entity = Entity(self.next_entity); 38 + self.next_entity += 1; 39 + entity 40 + } 41 + 42 + pub fn insert_session( 43 + &mut self, 44 + session_id: session::SessionId, 45 + uid: u32, 46 + username: String, 47 + vt: u32, 48 + seat: Option<String>, 49 + timestamp: time::SystemTime, 50 + leader_id: i32, 51 + objects: Vec<session_core_session::SessionCoreSession>, 52 + active_state: session_core_v1::ActiveState, 53 + ) -> Entity { 54 + let entity = self.entity(); 55 + self.session_entities.insert(session_id, entity); 56 + self.insert(entity, Uid(uid)); 57 + self.insert(entity, Username(username)); 58 + self.insert(entity, Vt(vt)); 59 + self.insert(entity, Seat(seat)); 60 + self.insert(entity, Timestamp(timestamp)); 61 + self.insert(entity, LeaderId(leader_id)); 62 + self.insert(entity, SessionObjects(objects)); 63 + self.insert(entity, ActiveState(active_state)); 64 + entity 65 + } 66 + 67 + pub fn session_entity(&self, session_id: session::SessionId) -> Option<Entity> { 68 + self.session_entities.get(&session_id).copied() 69 + } 70 + 71 + pub fn insert<C>(&mut self, entity: Entity, component: C) 72 + where 73 + C: Component, 74 + { 75 + let storage = C::storage(self); 76 + if storage.len() <= entity.0 { 77 + storage.reserve(entity.0 + 1 - storage.len()); 78 + storage.resize_with(entity.0 + 1, || None); 79 + } 80 + storage[entity.0] = Some(component); 81 + } 82 + 83 + pub fn get<C>(&self, entity: Entity) -> Option<&C> 84 + where 85 + C: Component, 86 + { 87 + C::storage_ref(self).get(entity.0)?.as_ref() 88 + } 89 + 90 + pub fn get_mut<C>(&mut self, entity: Entity) -> Option<&mut C> 91 + where 92 + C: Component, 93 + { 94 + C::storage(self).get_mut(entity.0)?.as_mut() 95 + } 96 + 97 + pub fn remove_entity(&mut self, entity: Entity) { 98 + self.free_entities.push(entity); 99 + } 100 + }
+3
daemon/src/main.rs
··· 16 16 mod cgroup; 17 17 mod client; 18 18 mod device; 19 + mod ecs; 19 20 mod seat; 20 21 mod session; 21 22 mod terminal; ··· 94 95 next_client_id: client::ClientId, 95 96 clients: Vec<rc::Rc<cell::RefCell<client::Client>>>, 96 97 seat_access: SeatAccess, 98 + world: ecs::World, 97 99 } 98 100 99 101 impl Sessiond { ··· 395 397 next_client_id: client::ClientId::from_raw(1), 396 398 clients: Vec::new(), 397 399 seat_access, 400 + world: ecs::World::new(), 398 401 }; 399 402 400 403 let path = path::Path::new("/run/sessiond.sock");
+1 -1
daemon/src/session.rs
··· 1 1 use crate::{session_core_session, session_core_v1}; 2 2 use std::time; 3 3 4 - #[derive(Clone, Copy, PartialEq, Eq)] 4 + #[derive(Clone, Copy, PartialEq, Eq, Hash)] 5 5 pub struct SessionId(u32); 6 6 7 7 impl SessionId {