Oters

Oters (Oxidized Temporal Reactive Streams) is a functional reactive programming language designed for intuitively building GUIs based on Patrick Bahr's type system.

Documentation for the language can be found here.


Features


Dependencies

Oters relies on the macroquad crate for its GUI functionality. This crate requires certain system dependencies. Specifically on Linux:

```

ubuntu system dependencies

apt install pkg-config libx11-dev libxi-dev libgl1-mesa-dev libasound2-dev

fedora system dependencies

dnf install libX11-devel libXi-devel mesa-libGL-devel alsa-lib-devel

arch linux system dependencies

pacman -S pkg-config libx11 libxi mesa-libgl alsa-lib ```


Usage

Oters works as a Rust library and so must be included into your Rust project like any other dependency:

toml [dependencies] oters = "0.1.2"

Running an Oters file requires a single macro call in your main function:

rust fn main() { let config = oters::WindowConfig { title: "My Oters App".to_string(), dimensions: (800, 600), resizable: true, fullscreen: false, icon: None, }; oters::run!(vec!["./examples/demo/demo.otrs".to_string()], config,); }

Note that files passed to the run! macro must be in order of dependency. So if you have two files main.otrs and logic.otrs, and the former relies on the latter, then logic.otrs must come before main.otrs in the Vec.

And importing a Rust function into Oters, is also done through a single macro call:

```rust

[export_oters]

fn printmessage(s: String) { println!("This message is being printed from a Rust function: \n{s}"); } // Can now call the function printmessage from your Oters file ```


Examples

A token example taken from examples/demo/demo.otrs:

``` use std::stream::const use std::stream::head use gui::widget::* use gui::color::* use gui::shape::*

let ui = gui::frame ((100,50), (250, 100))

let (btnid, btnstream) = button ui (100, 50) (const "Click me!")

let counter = { let aux = fn n -> { let delta = if head btnstream then 1 else 0; (n + delta) << @(aux (n + delta)) }; aux 0 } let counterstring = std::inttostring (head counter) << @counter_string

let (labid, labstream) = label ui (100, 50) counter_string

let (grpid, grpstream) = hgroup ui (250,100) (const [btnid, labid]) (Alignment::Top)

let _ = gui::attachroot (ui, grpid)

let circlecolor = (if head counter % 3 == 0 then red else if head counter %3 == 1 then green else blue) << @circlecolor

let circle = (drawshape (Shape::Circle((200,200), 30, head circlecolor))) << @circle ```