veecle-os-runtime 0.1.0

Veecle OS Runtime
Documentation
#![expect(missing_docs)]

use core::convert::Infallible;
use core::fmt::Debug;
use core::sync::atomic::{AtomicUsize, Ordering};
use std::future::poll_fn;
use std::sync::atomic::Ordering::SeqCst;
use std::task::Poll;
use veecle_os_runtime::{ExclusiveReader, Reader, Storable, Writer};

static READ_COUNTER: AtomicUsize = AtomicUsize::new(0);

#[derive(Debug, PartialEq, Clone, Storable)]
pub struct Sensor(pub u8);

#[veecle_os_runtime::actor]
async fn exclusive_read_actor(mut reader: ExclusiveReader<'_, Sensor>) -> Infallible {
    loop {
        if let Some(value) = reader.take() {
            println!("Value received: {value:?}");
            READ_COUNTER.fetch_add(1, Ordering::AcqRel);
        } else {
            reader.wait_for_update().await;
        }
    }
}

#[veecle_os_runtime::actor]
async fn write_actor(mut writer: Writer<'_, Sensor>) -> Infallible {
    for index in 0..10 {
        writer.write(Sensor(index)).await;
    }
    core::future::pending().await
}

#[test]
fn main() {
    veecle_os_test::block_on_future(veecle_os_test::execute! {
        store: [Sensor],
        actors: [
            ExclusiveReadActor,
            WriteActor,
        ],
        validation: async || {
            poll_fn(|cx| {
                if READ_COUNTER.load(SeqCst) == 10 {
                    return Poll::Ready(());
                }
                cx.waker().wake_by_ref();
                Poll::Pending
            }).await;
        }
    });
    assert_eq!(READ_COUNTER.load(SeqCst), 10);
}

#[test]
#[should_panic(expected = "conflict with exclusive reader for `exclusive_reader::Sensor`")]
fn not_exclusive_first() {
    #[veecle_os_runtime::actor]
    async fn non_excl_read_actor(_reader: Reader<'_, Sensor>) -> Infallible {
        core::future::pending().await
    }

    futures::executor::block_on(veecle_os_runtime::execute! {
        store: [Sensor],
        actors: [
            ExclusiveReadActor,
            WriteActor,
            NonExclReadActor,
        ],
    });
}

#[test]
#[should_panic(expected = "conflict with exclusive reader for `exclusive_reader::Sensor`")]
fn not_exclusive_last() {
    #[veecle_os_runtime::actor]
    async fn non_excl_read_actor(_reader: Reader<'_, Sensor>) -> Infallible {
        core::future::pending().await
    }

    futures::executor::block_on(veecle_os_runtime::execute! {
        store: [Sensor],
        actors: [
            WriteActor,
            NonExclReadActor,
            ExclusiveReadActor,
        ],
    });
}