Skip to content

Instantly share code, notes, and snippets.

iogui

A GUI library that is less of a library and more of a binary, with communication done solely through stdin/stdout. A client would spawn iogui as a child process, send a description of what the GUI should look like in a compact TCL-like manner, and iogui will then send back events whenever something happens (e.g. a button was pressed, an input's text was changed).

Given that communication will be done via text, the following limitations will exist:

  • No custom widgets or canvas surfaces
  • No custom image support
  • No video/audio support
  • No mouse pointer motion events (at least not by default)
  • No custom animations (although "move x to y over n seconds using y function", should be possible)
use bytes::{Bytes, BytesMut, BufMut};
use futures::future::{self, Either};
use futures::sync::mpsc;
use futures::Poll;
use std::cell::RefCell;
use std::collections::HashMap;
use std::net::SocketAddr;
use std::rc::Rc;
use tokio::codec::{FramedRead, LinesCodec};
use tokio::io::{write_all, AsyncRead, ReadHalf};

I want hot-reloading.

In the past I achieved this by self-replacing the process via execve, and letting the new process inherit all the socket file descriptors. This worked on both Linux and Windows, but it's hard to implement.

So I'll do this intead:

  • A thin connection manager whose job is to listen on all the ports, and relay messages
  • The flow: input-socket -> subprocess stdin -> subprocess stdout -> output-socket
  • It can spawn and manage a subprocess. If the subprocess quits, it will restart it.
  • Maybe in the future it can do so for multiple processes.
@andreivasiliu
andreivasiliu / 0-minitrack.rs
Last active March 10, 2019 07:07
minitrack
extern crate crossbeam;
use std::io::{stdin, BufRead, BufReader};
use std::process::{Command, Stdio, ExitStatus};
use crossbeam::channel::{Sender, Receiver, unbounded};
#[derive(Debug)]
enum ProcessEvent {
ProcessStarted(u32),
Stdout(String),
use std::process::{Command, Stdio, ExitStatus};
use std::io::BufReader;
use tokio_process::CommandExt;
use futures::{Future, Stream, Sink};
use futures::sync::mpsc::{Sender, SendError, channel};
#[derive(Debug)]
enum ProcessEvent {
ProcessStarted,
Stdout(String),

Things I need to solve:

  • Coordinate system
  • Collision detection, if any
  • Collision shapes
  • Physics, if any
  • Nudging, if any
  • Path-finding
  • Map structure

Coordinate system

@andreivasiliu
andreivasiliu / try1.rs
Last active June 22, 2019 20:46
Multi-Loader/Provider
struct Loader<D, V> {
dns: D,
vma: V,
}
fn new_loader() -> Loader<(), ()> {
Loader {
dns: (),
vma: (),
}
# Partial Pest variant of https://github.com/andreivasiliu/TinyRaytracerInD/blob/06063dbf20036970b3446ae97a044570035f5872/src/sceneparser/GrammarConstants.d
alpha = { 'a'..'z' | 'A'..'Z' }
digit = { '0'..'9' }
ident = { alpha ~ (alpha | digit)* }
ident_list = _{ ident ~ (" " ~ ident)* }
use mio::{Poll, Token, Ready, PollOpt, Events, Evented};
use std::process::{Command, Stdio};
use mio_child_process::{CommandAsync, Process};
use std::sync::mpsc::TryRecvError;
use std::collections::HashMap;
use mio_extras::channel::{sync_channel, SyncSender};
use std::io::{BufRead, stdin};
fn read_commands<R: BufRead>(reader: R, output: SyncSender<String>) {
for line in reader.lines() {
def show_map() -> Iterable[str]:
yield f"The map has {len(bat_map)} rooms."
if not current_room:
return
yield f"Current room: {current_room.title}"
links = bat_links.get(current_room.room_id)
if links:
inc = len(links.incoming)