1use crate::query::LkQuery;
8use linkspace_core::query::Query as QueryImpl;
9#[doc(hidden)]
10impl From<LkQuery> for QueryImpl {
11 fn from(val: LkQuery) -> Self {
12 val.0
13 }
14}
15#[doc(hidden)]
16impl From<QueryImpl> for LkQuery {
17 fn from(value: QueryImpl) -> Self {
18 LkQuery(value)
19 }
20}
21impl crate::query::LkQuery {
22 #[doc(hidden)]
23 pub fn as_impl(&self) -> &QueryImpl {
24 unsafe { &*(self as *const LkQuery as *const QueryImpl) }
25 }
26 #[doc(hidden)]
27 pub fn from_impl(q: &QueryImpl) -> &LkQuery {
28 unsafe { &*(q as *const QueryImpl as *const LkQuery) }
29 }
30}
31
32#[cfg(any(feature = "lmdb", feature = "inmem"))]
33pub mod sys_interop {
34 use crate::system::LkSystem;
35 use std::ops::ControlFlow;
36
37 use linkspace_core::{prelude::Point, query::WatchIDRef};
38 pub use linkspace_system::System;
39 use linkspace_system::{
40 handlers::{PointStreamHandler, StopReason},
41 thread_local::{use_sys, with_system},
42 };
43 #[doc(hidden)]
44 impl From<System> for LkSystem {
45 fn from(value: System) -> Self {
46 LkSystem(value)
47 }
48 }
49 #[doc(hidden)]
50 impl From<LkSystem> for System {
51 fn from(val: LkSystem) -> Self {
52 val.0
53 }
54 }
55 impl LkSystem {
56 #[doc(hidden)]
57 pub fn as_impl(&self) -> &System {
58 unsafe { &*(self as *const LkSystem as *const System) }
59 }
60 #[doc(hidden)]
61 pub fn from_impl(lks: &System) -> &LkSystem {
62 unsafe { &*(lks as *const System as *const LkSystem) }
63 }
64 #[doc(hidden)]
65 pub fn active() -> LkSystem {
66 LkSystem(linkspace_system::thread_local::get_system().unwrap())
67 }
68 }
69 impl linkspace_system::eval::OpenSystem for &LkSystem {
70 fn lk(self) -> anyhow::Result<System> {
71 Ok(self.0.clone())
72 }
73 }
74
75 #[derive(Debug, Clone)]
77 pub struct Handler<T: ?Sized>(pub T);
78 use crate::query::LkQuery;
79
80 use crate::system::cb::PointHandler;
81 impl<T: PointHandler + ?Sized + 'static> linkspace_system::handlers::PointStreamHandler
82 for Handler<T>
83 {
84 fn handle_point(
85 &mut self,
86 point: &dyn Point,
87 watch_id: Option<&WatchIDRef>,
88 rx: &System,
89 ) -> ControlFlow<()> {
90 use_sys(rx, || self.0.on_point(point, watch_id))
91 }
92 fn stopped(
93 &mut self,
94 query: &linkspace_core::prelude::Query,
95 sys: &System,
96 reason: StopReason,
97 total: u64,
98 watched: u64,
99 ) {
100 let query = LkQuery::from_impl(query);
101 use_sys(sys, || self.0.on_close(query, reason, total, watched))
102 }
103 }
104 impl<T: PointHandler + 'static> linkspace_system::handlers::HeapPointStreamHandler for Handler<T> {}
105
106 impl<T: PointStreamHandler + ?Sized + 'static> PointHandler for Handler<T> {
107 fn on_point(&mut self, point: &dyn Point, watch: Option<&WatchIDRef>) -> ControlFlow<()> {
108 with_system(|lks| self.0.handle_point(point, watch, &lks))
109 }
110
111 fn on_close(
112 &mut self,
113 q: &LkQuery,
114 reason: StopReason,
115 total_calls: u64,
116 watch_calls: u64,
117 ) {
118 with_system(|lks| {
119 self.0
120 .stopped(q.as_impl(), &lks, reason, total_calls, watch_calls)
121 })
122 }
123 }
124}