Skip to content

Commit

Permalink
Std: Future
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanjermakov committed Apr 9, 2024
1 parent 2d1b907 commit d1d1dc5
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/std/future.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* @param {function(): Unit} f
* @param {Int} delay
* @returns {Unit}
*/
function deferFor(f, delay) {
setTimeout(f, delay)
}
89 changes: 89 additions & 0 deletions src/std/future.no
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use std::ref::eqRef

pub type Future<T>(
f: ||T|: Unit|: Unit,
subscribers: List<|T|: Unit>,
state: FutureState<T>,
)

// TODO: should be private, but there is a bug with visibility in impls
pub type FutureState<T> {
Created(),
Queued(),
Pending(),
Resolved(value: T),
}

impl <T> Trace for FutureState<T> {}

impl <T> Future<T> {
pub fn new(f: ||T|: Unit|: Unit): Self {
Future(f, [], Created())
}

pub fn onResolve(self, f: |T|: Unit): Self {
match self.state {
Resolved(value) {
f(value)
return self
}
_ {}
}
self.subscribers.add(f)
self
}

pub fn spawn(self, runtime: Runtime): Self {
runtime.spawn(self)
}
}

pub type Runtime(
// TODO: use std::time::Duration
pollingRate: Int,
queue: List<Future<_>>,
pending: List<Future<_>>,
)

impl Runtime {
pub fn new(): Runtime {
Runtime::withPollingRate(10)
}

pub fn withPollingRate(pollingRate: Int): Runtime {
Runtime(pollingRate, [], [])
}

pub fn loop(self): Unit {
while self.queue.count() > 0 {
let next = self.queue.popFront()!
next.state = Pending()
self.pending.add(next)
let _ = (next.f)(|res| {
next.state = Resolved(res)
for s in next.subscribers {
s(res)
}
next.subscribers.clear()
self.pending.popAt(self.pending.iter().position(|e| { eqRef(next, e) })!)
unit
})
}
if self.queue.count() > 0 || self.pending.count() > 0 {
deferFor(|| { self.loop() }, self.pollingRate)
}
}

pub fn spawn<T>(self, future: Future<T>): Future<T> {
self.queue.add(future)
future.state = Queued()
future
}
}

pub fn defer(f: ||: Unit): Unit {
deferFor(f, 0)
}

pub fn deferFor(f: ||: Unit, delay: Int): Unit

1 change: 1 addition & 0 deletions src/std/prelude.no
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ pub use std::{
io::{ println, show::Show, trace::Trace },
option::Option::{ self, Some, None },
result::Result::{ self, Ok, Error },
future::Future,
}

0 comments on commit d1d1dc5

Please sign in to comment.