Skip to content

Commit

Permalink
Tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
tommy-xr committed Jun 7, 2024
1 parent 6f40dbe commit db7ad6a
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 42 deletions.
2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,4 @@ members = [
"runtime/functor-runtime-desktop",
"runtime/functor-runtime-web",
"src",
"examples/Pong/build-native",
"examples/Pong/build-wasm",
]
81 changes: 60 additions & 21 deletions cli/src/commands/develop.rs
Original file line number Diff line number Diff line change
@@ -1,57 +1,86 @@
use colored::*;
use std::io::{self, BufRead};
use std::env;
use std::io::{self, BufRead, Error};
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use tokio::io::{AsyncBufReadExt, BufReader};
use tokio::process::Command as TokioCommand;

struct CommandSpec<'a> {
prefix: &'a str,
cmd: &'a str,
cwd: &'a str,
args: Vec<&'a str>,
env: Vec<(&'a str, &'a str)>,
}

pub async fn execute(working_directory: &str) -> io::Result<()> {
let cwd_path = Path::new(working_directory);
let build_native_path = Path::new(&"build-native");
let build_native_wd = cwd_path.join(build_native_path);

// Define the commands to run
let functor_runner_exe =
get_nearby_bin(&"functor-runner").expect("functor-runner should be available");

let target_dir = build_native_path.join(Path::new(&"target/debug"));

let commands = vec![
(
"[1: Build F#]",
working_directory,
"watchexec",
vec![
CommandSpec {
prefix: "[1: Build F#]",
cmd: "watchexec",
cwd: working_directory,
env: vec![],
args: vec![
"-e",
"fs",
"--no-process-group",
"--",
"npm run build:examples:pong:rust",
],
),
(
"[2: Build Rust]",
build_native_wd.to_str().unwrap(),
"watchexec",
vec!["-w", "..", "-e", "rs", "--", "cargo build"],
),
},
CommandSpec {
prefix: "[2: Build Rust]",
cmd: "watchexec",
cwd: build_native_wd.to_str().unwrap(),
env: vec![],
args: vec!["-w", "..", "-e", "rs", "--", "cargo build"],
},
CommandSpec {
prefix: "[3: Functor Runner]",
cmd: functor_runner_exe.to_str().unwrap(),
cwd: build_native_wd.to_str().unwrap(),
env: vec![],
args: vec![],
},
];

// Spawn the processes
let mut handles = vec![];
for (prefix, cwd, cmd, args) in commands {
println!("Using working dir: {}", cwd);
let mut command = TokioCommand::new(cmd);
for command_spec in commands {
println!("Using working dir: {}", &command_spec.cwd);
let mut command = TokioCommand::new(&command_spec.cmd);
println!("-- Running command: {}", &command_spec.cmd);

// Set environment variables if any
for (key, value) in command_spec.env {
command.env(key, value);
}

command
.current_dir(Path::new(cwd))
.args(&args)
.current_dir(Path::new(&command_spec.cwd))
.args(&command_spec.args)
.stdout(Stdio::piped())
.stderr(Stdio::piped());
let mut child = command.spawn()?;
let stdout = child.stdout.take().unwrap();
let stderr = child.stderr.take().unwrap();

// Handle stdout
let stdout_handle = handle_output(prefix.to_string(), stdout, true);
let stdout_handle = handle_output(command_spec.prefix.to_string(), stdout, true);
handles.push(tokio::spawn(stdout_handle));

// Handle stderr
let stderr_handle = handle_output(prefix.to_string(), stderr, false);
let stderr_handle = handle_output(command_spec.prefix.to_string(), stderr, false);
handles.push(tokio::spawn(stderr_handle));
}

Expand All @@ -75,3 +104,13 @@ async fn handle_output(prefix: String, stream: impl tokio::io::AsyncRead + Unpin
println!("{}: {}", colored_prefix, line);
}
}

fn get_nearby_bin(file: &str) -> io::Result<PathBuf> {
let curent_exe = env::current_exe()?;

let parent = curent_exe.parent().unwrap();

let ret = parent.join(&file);

Ok(ret)
}
9 changes: 7 additions & 2 deletions examples/Pong/build-native/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
[package]
name = "pong_native"
name = "game_native"
version = "0.1.0"
edition = "2021"

[build]
target-dir = "../target"

[workspace]

[lib]
name = "pong_native"
name = "game_native"
path = "../Pong.rs"
crate-type = ["dylib"]

Expand Down
17 changes: 9 additions & 8 deletions runtime/functor-runtime-desktop/src/hot_reload_game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,31 @@ use libloading::{Library, Symbol};

use crate::game::Game;

pub struct HotReloadGame {
pub struct HotReloadGame<'a> {
// Utils for constructing the next lib path
file_stem: String,
extension: String,
counter: u32,

// Current hot reload state
latest_lib_path: String,
latest_lib_path: &'a str,
library: Option<Library>,
}

impl Game for HotReloadGame {
impl<'a> Game for HotReloadGame<'a> {
fn render(&mut self) -> Scene3D {
println!("Rendering");
// println!("Rendering");
unsafe {
let render_func: Symbol<fn() -> Scene3D> =
self.library.as_ref().unwrap().get(b"test_render").unwrap();
render_func()
}
}
}
impl HotReloadGame {
pub fn create(path: String) -> HotReloadGame {
impl<'a> HotReloadGame<'a> {
pub fn create(path: &str) -> HotReloadGame {
let counter = 0;
let lib_path = Path::new(&path);
let lib_path = Path::new(path);
let file_stem = lib_path
.file_stem()
.map(|s| s.to_string_lossy().to_string())
Expand Down Expand Up @@ -85,9 +85,10 @@ impl HotReloadGame {
}

let temp_dir = tempdir().expect("Failed to create temporary directory");
println!("Copying to: {}", &temp_dir.path().to_str().unwrap());
let new_file_name = temp_dir.path().join(self.get_next_destination_name());
// TODO: Better definition of path here - don't hardcode target/debug
let source_path = &format!("target/debug/{}", self.latest_lib_path);
let source_path = self.latest_lib_path;
fs::copy(source_path, &new_file_name).expect("Cmtpy should succeed");
println!("Loading from: {:?}", &new_file_name);

Expand Down
15 changes: 6 additions & 9 deletions runtime/functor-runtime-desktop/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ mod hot_reload_game;
pub fn main() {
// Load game

let game_path = Path::new("target/debug/libgame_native.dylib");

let file_changed = Arc::new(AtomicBool::new(false));
let file_changed_watcher = Arc::clone(&file_changed);
let watcher_thread = std::thread::spawn(move || {
Expand All @@ -36,12 +38,7 @@ pub fn main() {

let mut had_remove_event = false;

watcher
.watch(
Path::new("target/debug/libpong_native.dylib"),
RecursiveMode::Recursive,
)
.unwrap();
watcher.watch(game_path, RecursiveMode::Recursive).unwrap();

println!("watcher created!");
loop {
Expand Down Expand Up @@ -76,10 +73,10 @@ pub fn main() {

let mut test_render_func2: Option<Arc<Symbol<fn() -> Scene3D>>> = None;

let game_filename = library_filename("pong_native");
let mut game = HotReloadGame::create(game_filename.to_string_lossy().to_string());
println!("Trying to open from: {:?}", &game_path);
let mut game = HotReloadGame::create(&game_path.to_str().unwrap());
unsafe {
let lib = Library::new(&game_filename).unwrap(); // Load the "hello_world" library
let lib = Library::new(&game_path).unwrap(); // Load the "hello_world" library
let func: Symbol<fn(f64)> = lib.get(b"dynamic_call_from_rust").unwrap(); // Get the function pointer

let test_render_func: Symbol<fn() -> Scene3D> = lib.get(b"test_render").unwrap(); // Get the function pointer
Expand Down

0 comments on commit db7ad6a

Please sign in to comment.