Compare commits

..

2 Commits

Author SHA1 Message Date
Scott Richmond
a444f789f3 add new actor functions 2025-07-06 19:40:55 -04:00
Scott Richmond
842f1e7634 release build 2025-07-06 19:06:27 -04:00
5 changed files with 57 additions and 5 deletions

View File

@ -1049,6 +1049,15 @@ fn send {
fn spawn! {
"Spawns a process. Takes a 0-argument (nullary) function that will be executed as the new process. Returns a keyword process ID (pid) of the newly spawned process."
(f as :fn) -> {
let new_pid = base :process (:spawn, f)
link! (new_pid)
new_pid
}
}
fn fledge! {
"Spawns a process and then immediately unlinks from it. Takes a 0-argument (nullary) function that will be executed as the new process. Returns a keyword process ID (pid) of the newly fledged process."
(f as :fn) -> base :process (:spawn, f)
}
@ -1067,6 +1076,11 @@ fn link! {
(pid as :keyword) -> base :process (:link, pid)
}
fn unlink! {
"Unlinks this process from the other process."
(pid as :keyword) -> base :process (:unlink, pid)
}
fn monitor! {
"Subscribes this process to another process's exit signals. There are two possibilities: a panic or a return. Exit signals are in the form of `(:exit, pid, (:ok, value)/(:err, msg))`."
(pid as :keyword) -> base :process (:monitor, pid)
@ -1092,6 +1106,19 @@ fn await! {
panic! "Monitored process {pid} panicked with {msg}" }
}
}
(pids as :list) -> {
each! (pids, monitor!)
fold (
(fn (results, pid) -> append (results, await! (pid)))
pids
[]
)
}
}
fn hibernate! {
"Ensures the current process will never return, allowing other processes to do their thing indefinitely. Does not unlink the process, so panics in linked processes will still bubble up."
() -> receive { _ -> hibernate! () }
}
fn heed! {
@ -1487,6 +1514,8 @@ fn key_pressed? {
monitor!
await!
heed!
unlink!
hibernate!
spawn_turtle!

View File

@ -403,7 +403,7 @@ function __wbg_get_imports() {
_assertBoolean(ret);
return ret;
};
imports.wbg.__wbindgen_closure_wrapper8189 = function() { return logError(function (arg0, arg1, arg2) {
imports.wbg.__wbindgen_closure_wrapper8194 = function() { return logError(function (arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 363, __wbg_adapter_20);
return ret;
}, arguments) };

Binary file not shown.

View File

@ -117,7 +117,7 @@ pub fn words(str: &Value) -> Value {
let mut words = Vector::new();
let mut word = String::new();
for char in str.chars() {
if char.is_alphanumeric() {
if char.is_alphanumeric() || char == '\'' {
word.push(char)
} else if !word.is_empty() {
words.push_back(Value::from_string(word));

View File

@ -292,9 +292,10 @@ impl Creature {
// console_log!("sending exit signal {exit_signal}");
self.send_msg(Value::Keyword(pid), exit_signal);
}
for pid in self.siblings.clone() {
self.zoo.borrow_mut().kill(pid);
}
// returns no longer kill siblings
// for pid in self.siblings.clone() {
// self.zoo.borrow_mut().kill(pid);
// }
}
// TODO: fix these based on what I decide about `link` & `monitor`
@ -304,6 +305,7 @@ impl Creature {
unreachable!("expected keyword pid in monitor");
};
if other != self.pid {
self.unlink(Value::Keyword(other));
let mut other = self.zoo.borrow_mut().catch(other);
other.parents.push(self.pid);
self.zoo.borrow_mut().release(other);
@ -312,6 +314,26 @@ impl Creature {
self.push(Value::Keyword("ok"));
}
fn delete_from_siblings(&mut self, other: &'static str) {
let idx = self.siblings.iter().position(|pid| other == *pid);
if let Some(idx) = idx {
self.siblings.swap_remove(idx);
}
}
fn unlink(&mut self, other: Value) {
let Value::Keyword(other) = other else {
unreachable!("expected keyword pid in unlink")
};
if other != self.pid {
self.delete_from_siblings(other);
let mut other = self.zoo.borrow_mut().catch(other);
other.delete_from_siblings(self.pid);
self.zoo.borrow_mut().release(other);
}
self.push(Value::Keyword("ok"))
}
fn link(&mut self, other: Value) {
let Value::Keyword(other) = other else {
unreachable!("expected keyword pid in link");
@ -359,6 +381,7 @@ impl Creature {
}
"link" => self.link(args[1].clone()),
"monitor" => self.monitor(args[1].clone()),
"unlink" => self.unlink(args[1].clone()),
"flush" => {
let msgs = self.mbx.iter().cloned().collect::<Vec<_>>();
let msgs = Vector::from(msgs);