This commit is contained in:
Daniel Flanagan 2023-11-10 17:10:36 -06:00
parent de2dcd0cf6
commit a5bef250c1
Signed by: lytedev
GPG key ID: 5B2020A0F9921EF4
4 changed files with 120 additions and 72 deletions

50
src/counter.rs Normal file
View file

@ -0,0 +1,50 @@
use std::collections::HashSet;
use lunatic::{abstract_process, ap::Config, Process};
pub struct Counter {
counter: i64,
subscribers: HashSet<Process<i64>>,
}
#[abstract_process(visibility = pub)]
impl Counter {
#[init]
pub fn init(_: Config<Self>, start: i64) -> Result<Self, ()> {
Ok(Self {
counter: start,
subscribers: HashSet::new(),
})
}
#[handle_message]
pub fn subscribe(&mut self, m: Process<i64>) {
// monitor the process so we can remove it from this list when it dies
// let p = Process::spawn_link(self.counter, |capture, m: Mailbox<()>| {
// });
// add it to our list of subscribers
self.subscribers.insert(m);
}
fn notify(&self) {
for s in self.subscribers.iter() {
s.send(self.counter)
}
}
#[handle_message]
pub fn increment(&mut self) {
self.counter += 1;
}
#[handle_message]
pub fn decrement(&mut self) {
self.counter -= 1;
}
#[handle_request]
pub fn count(&self) -> i64 {
self.counter
}
}

63
src/counter_view.rs Normal file
View file

@ -0,0 +1,63 @@
use crate::counter::*;
use lunatic::{ap::ProcessRef, spawn};
use serde::{Deserialize, Serialize};
use submillisecond_live_view::prelude::*;
#[derive(Clone, Serialize, Deserialize)]
pub struct CounterView {
global_counter: ProcessRef<Counter>,
current_value: i64,
}
impl LiveView for CounterView {
type Events = (Increment, Decrement);
fn mount(_uri: Uri, socket: Option<Socket>) -> Self {
println!("{:?}", socket.is_some());
let global_counter = ProcessRef::<Counter>::lookup(&"global_counter").unwrap();
let current_count = global_counter.count();
let mut result = Self {
global_counter,
current_value: current_count,
};
spawn!(|m: Mailbox<i64>| {
loop {
result.current_value = m.receive();
}
});
result
}
fn render(&self) -> Rendered {
html! {
button @click=(Increment) { "Increment" }
button @click=(Decrement) { "Decrement" }
p { "Count is " (self.current_value) }
}
}
}
#[derive(Deserialize)]
pub struct Increment {}
impl LiveViewEvent<Increment> for CounterView {
fn handle(state: &mut Self, _event: Increment) {
state.current_value += 1;
state.global_counter.increment()
}
}
#[derive(Deserialize)]
pub struct Decrement {}
impl LiveViewEvent<Decrement> for CounterView {
fn handle(state: &mut Self, _event: Decrement) {
state.current_value -= 1;
state.global_counter.decrement()
}
}
pub type Notified = i64;
impl LiveViewEvent<Notified> for CounterView {
fn handle(state: &mut Self, event: Notified) {
state.current_value = event;
}
}

View file

@ -1,38 +1,13 @@
use lunatic::supervisor::{Supervisor, SupervisorConfig, SupervisorStrategy}; mod counter;
use serde::{Deserialize, Serialize}; mod counter_view;
use counter::Counter;
use counter_view::CounterView;
use lunatic::supervisor::*;
use submillisecond::{router, static_router, Application}; use submillisecond::{router, static_router, Application};
use submillisecond_live_view::prelude::*; use submillisecond_live_view::prelude::*;
use lunatic::abstract_process;
use lunatic::ap::{Config, ProcessRef};
pub struct Counter(i64);
#[abstract_process(visibility = pub)]
impl Counter {
#[init]
fn init(_: Config<Self>, start: i64) -> Result<Self, ()> {
Ok(Self(start))
}
#[handle_message]
fn increment(&mut self) {
self.0 += 1;
}
#[handle_message]
fn decrement(&mut self) {
self.0 -= 1;
}
#[handle_request]
fn count(&self) -> i64 {
self.0
}
}
struct Sup; struct Sup;
impl Supervisor for Sup { impl Supervisor for Sup {
type Arg = (); type Arg = ();
// Start 1 child and monitor it for failures. // Start 1 child and monitor it for failures.
@ -49,48 +24,8 @@ fn main() -> std::io::Result<()> {
Sup::init(&mut supconf, ()); Sup::init(&mut supconf, ());
Application::new(router! { Application::new(router! {
"/" => CounterView::handler("index.html", "#app") "/" => CounterView::handler("./static/index.html", "#app")
"/static" => static_router!("./static") "/static" => static_router!("./static")
}) })
.serve("127.0.0.1:3000") .serve("127.0.0.1:3000")
} }
#[derive(Clone, Serialize, Deserialize)]
struct CounterView {
global_counter: ProcessRef<Counter>,
}
impl LiveView for CounterView {
type Events = (Increment, Decrement);
fn mount(_uri: Uri, _socket: Option<Socket>) -> Self {
let global_counter = ProcessRef::<Counter>::lookup(&"global_counter").unwrap();
Self { global_counter }
}
fn render(&self) -> Rendered {
html! {
button @click=(Increment) { "Increment" }
button @click=(Decrement) { "Decrement" }
p { "Count is " (self.global_counter.count()) }
}
}
}
#[derive(Deserialize)]
struct Increment {}
impl LiveViewEvent<Increment> for CounterView {
fn handle(state: &mut Self, _event: Increment) {
state.global_counter.increment()
}
}
#[derive(Deserialize)]
struct Decrement {}
impl LiveViewEvent<Decrement> for CounterView {
fn handle(state: &mut Self, _event: Decrement) {
state.global_counter.decrement()
}
}