Init commit template for emscripten Rust

This commit is contained in:
Stephen Seo 2024-09-18 19:22:56 +09:00
commit 27d8ff1717
9 changed files with 178 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/dist/

41
Makefile Normal file
View file

@ -0,0 +1,41 @@
ifdef RELEASE
RUST_BUILD_TYPE := release
RUST_EXTRA_FLAGS := --release
C_OTHER_FLAGS := -DNDEBUG -O2
else
RUST_BUILD_TYPE := debug
RUST_EXTRA_FLAGS :=
C_OTHER_FLAGS := -Og
endif
CC := source ${HOME}/git/emsdk/emsdk_env.sh && emcc
CFLAGS := \
-Irust_src/include \
-sEXPORTED_FUNCTIONS=_main \
-sSTACK_SIZE=2097152 \
${C_OTHER_FLAGS}
# Check https://emscripten.org/docs/tools_reference/emcc.html for more compiler
# flags to pass to emcc.
HEADERS := \
rust_src/include/rust_src.h
all: dist
rust_src/target/wasm32-unknown-emscripten/${RUST_BUILD_TYPE}/libems_rust_template.a:
cd rust_src && cargo build --target=wasm32-unknown-emscripten ${RUST_EXTRA_FLAGS}
dist: rust_src/target/wasm32-unknown-emscripten/${RUST_BUILD_TYPE}/libems_rust_template.a src/main.c.o
@mkdir dist
${CC} -o dist/game.html ${CFLAGS} $^
ln -s game.html dist/index.html
.PHONY: clean
clean:
cd rust_src && cargo clean
rm -f src/*.c.o
rm -rf dist
%.c.o: %.c ${HEADERS}
${CC} -o $@ -c ${CFLAGS} $<

8
rust_src/.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
/target
# Added by cargo
#
# already existing elements were commented out
#/target

7
rust_src/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "ems_rust_template"
version = "0.1.0"

15
rust_src/Cargo.toml Normal file
View file

@ -0,0 +1,15 @@
[package]
name = "ems_rust_template"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["staticlib"]
[profile.release]
panic = "abort"
[profile.dev]
panic = "abort"
[dependencies]

View file

@ -0,0 +1,9 @@
#ifndef EMSCRIPTEN_RUST_TEMPLATE_RUST_SRC_H_
#define EMSCRIPTEN_RUST_TEMPLATE_RUST_SRC_H_
extern void *get_main_ctx(void);
extern void ctx_update(void *ctx);
extern void ctx_draw(void *ctx);
extern void ctx_resize_event_callback(void *ctx, int width, int height);
#endif

57
rust_src/src/lib.rs Normal file
View file

@ -0,0 +1,57 @@
use std::ffi;
#[no_mangle]
pub extern "C" fn get_main_ctx() -> *mut ffi::c_void {
Context::ems_new()
}
#[no_mangle]
pub extern "C" fn ctx_update(ctx: *mut ffi::c_void) {
unsafe {
let ctx: *mut Context = ctx as *mut Context;
(*ctx).update();
}
}
#[no_mangle]
pub extern "C" fn ctx_draw(ctx: *mut ffi::c_void) {
unsafe {
let ctx: *mut Context = ctx as *mut Context;
(*ctx).draw();
}
}
#[no_mangle]
pub extern "C" fn ctx_resize_event_callback(ctx: *mut ffi::c_void, width: ffi::c_int, height: ffi::c_int) {
unsafe {
let ctx: *mut Context = ctx as *mut Context;
(*ctx).resize_event_callback(width, height);
}
}
struct Context {
}
impl Context {
pub fn new() -> Self {
Self {
}
}
pub fn ems_new() -> *mut ffi::c_void {
let ctx_box: Box<Context> = Box::new(Context::new());
Box::<Context>::leak(ctx_box) as *mut Context as *mut ffi::c_void
}
pub fn update(&mut self) {
println!("update called.");
}
pub fn draw(&mut self) {
println!("draw called.");
}
pub fn resize_event_callback(&mut self, width: ffi::c_int, height: ffi::c_int) {
println!("Resize event: {}, {}", width, height);
}
}

1
src/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*.c.o

39
src/main.c Normal file
View file

@ -0,0 +1,39 @@
#include <emscripten.h>
#include <emscripten/html5.h>
#include <rust_src.h>
EM_JS(int, canvas_get_width, (), {
return document.getElementById("canvas").clientWidth;
});
EM_JS(int, canvas_get_height, (), {
return document.getElementById("canvas").clientHeight;
});
void *main_init(void) {
return get_main_ctx();
}
EM_BOOL resize_event_callback(int event_type, const EmscriptenUiEvent *event, void *ud) {
if (event_type == EMSCRIPTEN_EVENT_RESIZE) {
ctx_resize_event_callback(ud, canvas_get_width(), canvas_get_height());
}
return false;
}
void main_loop_update(void *ud) {
ctx_update(ud);
ctx_draw(ud);
}
int main(void) {
void *ctx = main_init();
emscripten_set_resize_callback(
EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, false, resize_event_callback);
// This function never returns.
emscripten_set_main_loop_arg(main_loop_update, ctx, 0, 1);
return 0;
}