Skip to content

Commit

Permalink
wip: wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
nmeylan committed Jun 29, 2024
1 parent aa5e608 commit bf2aa95
Show file tree
Hide file tree
Showing 12 changed files with 2,312 additions and 83 deletions.
17 changes: 12 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 12 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,22 @@ eframe = { version = "0.27.2", default-features = false, features = [
"default_fonts",
"glow",
"wayland",

"wgpu",
"x11"] }
egui = { version = "0.27.2", default-features = false, features = [] }
egui_extras = { version = "0.27.2", default-features = false, features = ["svg"] }
json-flat-parser = {git = "https://github.com/nmeylan/json-parser-flat-format.git", rev = "2b168da", features = ["indexmap", "simdutf8"]}
json-flat-parser = {git = "https://github.com/nmeylan/json-parser-flat-format.git", rev = "51c3f76", features = ["indexmap", "simdutf8"]}
rayon = {version = "1.10.0"}
rfd = {version = "0.14.1"}
indexmap = "2.2.6"
#[patch."https://github.com/nmeylan/json-parser-flat-format.git"]
#json-flat-parser = {path = "/home/nmeylan/dev/ragnarok/json-flat-parser"}
#json-flat-parser = {path = "/home/nmeylan/dev/ragnarok/json-flat-parser"}

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2.92"
wasm-bindgen-futures = "0.4"
web-sys = { version = "0.3.69", features = ["console"], default-features = false }

[profile.release]
opt-level = 2
53 changes: 53 additions & 0 deletions scripts/build_web.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env bash
set -eu
script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
cd "$script_path/.."

./scripts/setup_web.sh

# This is required to enable the web_sys clipboard API which eframe web uses
# https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Clipboard.html
# https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html
export RUSTFLAGS=--cfg=web_sys_unstable_apis

CRATE_NAME="json-editor"

FEATURES="all-features"

OPEN=false
OPTIMIZE=false
BUILD=release
BUILD_FLAGS="--release"
WGPU=true
WASM_OPT_FLAGS="-O2 --fast-math -g"

OUT_FILE_NAME="json-editor"

FINAL_WASM_PATH=web/${OUT_FILE_NAME}.wasm

# Clear output from old stuff:
rm -f "${FINAL_WASM_PATH}"

echo "Building rust…"
echo "cargo build ${BUILD_FLAGS}"
cargo build \
${BUILD_FLAGS} \
--bin ${OUT_FILE_NAME} \
--target wasm32-unknown-unknown

# Get the output directory (in the workspace it is in another location)
# TARGET=`cargo metadata --format-version=1 | jq --raw-output .target_directory`
TARGET="target"

echo "Generating JS bindings for wasm…"
TARGET_NAME="${CRATE_NAME}.wasm"
WASM_PATH="${TARGET}/wasm32-unknown-unknown/$BUILD/$TARGET_NAME"
wasm-bindgen "${WASM_PATH}" --out-dir web --out-name ${OUT_FILE_NAME} --no-modules --no-typescript

if [[ "${OPTIMIZE}" = true ]]; then
echo "Optimizing wasm…"
# to get wasm-opt: apt/brew/dnf install binaryen
wasm-opt "${FINAL_WASM_PATH}" $WASM_OPT_FLAGS -o "${FINAL_WASM_PATH}"
fi

echo "Finished ${FINAL_WASM_PATH}"
10 changes: 10 additions & 0 deletions scripts/setup_web.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -eu
script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
cd "$script_path/.."

# Pre-requisites:
rustup target add wasm32-unknown-unknown

# For generating JS bindings:
cargo install --quiet wasm-bindgen-cli --version 0.2.92
9 changes: 7 additions & 2 deletions src/array_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ use json_flat_parser::{FlatJsonValue, JsonArrayEntries, JSONParser, ParseOptions
use json_flat_parser::serializer::serialize_to_json_with_option;


use crate::{ACTIVE_COLOR, ArrayResponse, concat_string, Window};
use crate::{ACTIVE_COLOR, ArrayResponse, concat_string, Window};
use crate::compatibility::InstantWrapper;
use crate::components::icon;
use crate::components::popover::PopupMenu;
use crate::fonts::{FILTER, THUMBTACK};
Expand Down Expand Up @@ -124,7 +125,11 @@ pub struct ArrayTable {
pub changed_scroll_to_column_value: bool,
pub changed_matching_column_selected: bool,
pub changed_matching_row_selected: bool,

#[cfg(not(target_arch = "wasm32"))]
pub changed_scroll_to_row_value: Option<Instant>,
#[cfg(target_arch = "wasm32")]
pub changed_scroll_to_row_value: Option<InstantWrapper>,

pub editing_index: RefCell<Option<(usize, usize, bool)>>,
pub editing_value: RefCell<String>,
Expand Down Expand Up @@ -811,7 +816,7 @@ impl ArrayTable {
pub fn reset_search(&mut self) {
self.scroll_to_row.clear();
self.matching_rows.clear();
self.changed_scroll_to_row_value = Some(Instant::now().sub(Duration::from_millis(1000)));
self.changed_scroll_to_row_value = Some(crate::compatibility::now().sub(Duration::from_millis(1000)));
self.matching_row_selected = 0;
}
}
141 changes: 141 additions & 0 deletions src/compatibility.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
use std::time::{Duration, Instant};
#[macro_export]
macro_rules! log {
() => {
#[cfg(not(target_arch = "wasm32"))]
print!("\n")
};
($($arg:tt)*) => {{
#[cfg(not(target_arch = "wasm32"))]
println!($($arg)*);
#[cfg(target_arch = "wasm32")]
web_sys::console::log_1(&std::format_args!($($arg)*).as_str().into());
}};
}

#[cfg(not(target_arch = "wasm32"))]
pub fn now() -> std::time::Instant {
crate::compatibility::now()
}
#[cfg(target_arch = "wasm32")]
pub fn now() -> crate::compatibility::InstantWrapper {
InstantWrapper::now()
}

#[cfg(target_arch = "wasm32")]
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Hash)]
pub struct InstantWrapper(Duration);



#[cfg(target_arch = "wasm32")]
impl InstantWrapper {
#[inline]
pub fn now() -> Self {
InstantWrapper(duration_from_f64(_now()))
}

#[inline]
pub fn duration_since(&self, earlier: InstantWrapper) -> Duration {
assert!(
earlier.0 <= self.0,
"`earlier` cannot be later than `self`."
);
self.0 - earlier.0
}

#[inline]
pub fn elapsed(&self) -> Duration {
Self::now().duration_since(*self)
}

#[inline]
pub fn checked_add(&self, duration: Duration) -> Option<InstantWrapper> {
self.0.checked_add(duration).map(InstantWrapper)
}

#[inline]
pub fn checked_sub(&self, duration: Duration) -> Option<InstantWrapper> {
self.0.checked_sub(duration).map(InstantWrapper)
}

#[inline]
pub fn checked_duration_since(&self, earlier: InstantWrapper) -> Option<Duration> {
if earlier.0 > self.0 {
None
} else {
Some(self.0 - earlier.0)
}
}

#[inline]
pub fn saturating_duration_since(&self, earlier: InstantWrapper) -> Duration {
self.checked_duration_since(earlier).unwrap_or_default()
}
}

#[cfg(target_arch = "wasm32")]
impl std::ops::Add<Duration> for InstantWrapper {
type Output = Self;

#[inline]
fn add(self, rhs: Duration) -> Self {
InstantWrapper(self.0 + rhs)
}
}

#[cfg(target_arch = "wasm32")]
impl std::ops::AddAssign<Duration> for InstantWrapper {
#[inline]
fn add_assign(&mut self, rhs: Duration) {
self.0 += rhs
}
}

#[cfg(target_arch = "wasm32")]
impl std::ops::Sub<Duration> for InstantWrapper {
type Output = Self;

#[inline]
fn sub(self, rhs: Duration) -> Self {
InstantWrapper(self.0 - rhs)
}
}

#[cfg(target_arch = "wasm32")]
impl std::ops::Sub<InstantWrapper> for InstantWrapper {
type Output = Duration;

#[inline]
fn sub(self, rhs: InstantWrapper) -> Duration {
self.duration_since(rhs)
}
}

#[cfg(target_arch = "wasm32")]
impl std::ops::SubAssign<Duration> for InstantWrapper {
#[inline]
fn sub_assign(&mut self, rhs: Duration) {
self.0 -= rhs
}
}

#[cfg(target_arch = "wasm32")]
fn duration_from_f64(millis: f64) -> Duration {
Duration::from_millis(millis.trunc() as u64)
+ Duration::from_nanos((millis.fract() * 1.0e6) as u64)
}

#[cfg(target_arch = "wasm32")]
fn _now() -> f64 {
let now = {
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
web_sys::js_sys::Reflect::get(&web_sys::js_sys::global(), &wasm_bindgen::JsValue::from_str("performance"))
.expect("failed to get performance from global object")
.unchecked_into::<web_sys::Performance>()
.now()
};

now
}
Loading

0 comments on commit bf2aa95

Please sign in to comment.