From df5a1a496128b5b5472ec3f6063cd5c22a15ac8f Mon Sep 17 00:00:00 2001 From: jprochazk <1665677+jprochazk@users.noreply.github.com> Date: Tue, 5 Dec 2023 18:35:39 +0100 Subject: [PATCH 1/2] remove usage of `build_demo_app.py` from `build_screenshot_compare.py` --- .../build_screenshot_compare.py | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/scripts/screenshot_compare/build_screenshot_compare.py b/scripts/screenshot_compare/build_screenshot_compare.py index 3cc591040076..92580d657e6d 100755 --- a/scripts/screenshot_compare/build_screenshot_compare.py +++ b/scripts/screenshot_compare/build_screenshot_compare.py @@ -8,7 +8,7 @@ - The screenshots listed in .fbs files (crates/re_types/definitions/rerun/**/*.fbs), and the corresponding code examples in the docs (docs/code-examples/*.rs) -- The `demo.rerun.io` examples, as built by the `build_demo_app.py` script. +- The `app.rerun.io` examples, as built by the `re_build_examples` script. The comparisons are generated in the `compare_screenshot` directory. Use the `--serve` option to show them in a browser. @@ -146,34 +146,27 @@ def collect_code_examples() -> Iterable[Example]: # ==================================================================================================== # DEMO EXAMPLES # -# We run the `build_demo_app.py` script and scrap the output "web_demo" directory. +# We run the `build_examples` script and scrap the output "example_data" directory. # ==================================================================================================== -BUILD_DEMO_APP_SCRIPT = RERUN_DIR / "scripts" / "ci" / "build_demo_app.py" - - -def build_demo_examples(skip_example_build: bool = False) -> None: - cmd = [ - str(BUILD_DEMO_APP_SCRIPT), - "--skip-build", # we handle that ourselves - ] - - if skip_example_build: - cmd.append("--skip-example-build") +def build_demo_examples() -> None: + cmd = ["cargo", "run", "--locked", "-p", "re_build_examples", "--", "example_data"] + run(cmd, cwd=RERUN_DIR) + cmd = ["cargo", "run", "--locked", "-p", "re_build_examples_manifest", "--", "example_data/examples_manifest.json"] run(cmd, cwd=RERUN_DIR) def collect_demo_examples() -> Iterable[Example]: - web_demo_example_dir = SCRIPT_DIR_PATH.parent.parent / "web_demo" / "examples" + web_demo_example_dir = RERUN_DIR / "example_data" assert web_demo_example_dir.exists(), "Web demos have not been built yet." - manifest = json.loads((web_demo_example_dir / "manifest.json").read_text()) + manifest = json.loads((web_demo_example_dir / "examples_manifest.json").read_text()) for example in manifest: name = example["name"] - rrd = web_demo_example_dir / f"{name}" / "data.rrd" + rrd = web_demo_example_dir / f"{name}.rrd" assert rrd.exists(), f"Missing {rrd} for {name}" yield Example( From a871e75d832d8a4a1f7638e5419d1b5d5e68df9d Mon Sep 17 00:00:00 2001 From: jprochazk <1665677+jprochazk@users.noreply.github.com> Date: Tue, 5 Dec 2023 18:36:14 +0100 Subject: [PATCH 2/2] rip out `build_demo_app.py` and associated assets --- .gitignore | 3 - scripts/ci/build_demo_app.py | 326 ------------------ scripts/ci/demo_assets/static/caret-down.svg | 3 - scripts/ci/demo_assets/static/caret-right.svg | 3 - scripts/ci/demo_assets/static/favicon.svg | 11 - .../demo_assets/static/github-mark-white.svg | 1 - scripts/ci/demo_assets/static/index.css | 312 ----------------- scripts/ci/demo_assets/static/index.html | 36 -- scripts/ci/demo_assets/static/index.js | 251 -------------- scripts/ci/demo_assets/static/manifest.json | 16 - scripts/ci/demo_assets/static/sw.js | 27 -- scripts/ci/demo_assets/templates/example.html | 101 ------ .../build_screenshot_compare.py | 8 +- 13 files changed, 4 insertions(+), 1094 deletions(-) delete mode 100755 scripts/ci/build_demo_app.py delete mode 100644 scripts/ci/demo_assets/static/caret-down.svg delete mode 100644 scripts/ci/demo_assets/static/caret-right.svg delete mode 100644 scripts/ci/demo_assets/static/favicon.svg delete mode 100644 scripts/ci/demo_assets/static/github-mark-white.svg delete mode 100644 scripts/ci/demo_assets/static/index.css delete mode 100644 scripts/ci/demo_assets/static/index.html delete mode 100644 scripts/ci/demo_assets/static/index.js delete mode 100644 scripts/ci/demo_assets/static/manifest.json delete mode 100644 scripts/ci/demo_assets/static/sw.js delete mode 100644 scripts/ci/demo_assets/templates/example.html diff --git a/.gitignore b/.gitignore index 5c9287d648f8..ab787d156bbb 100644 --- a/.gitignore +++ b/.gitignore @@ -44,9 +44,6 @@ perf.data* # Screenshots from samples etc. screenshot*.png -# Web demo app build -web_demo - # Saved example `.rrd` files example_data diff --git a/scripts/ci/build_demo_app.py b/scripts/ci/build_demo_app.py deleted file mode 100755 index f2252f0c1aa3..000000000000 --- a/scripts/ci/build_demo_app.py +++ /dev/null @@ -1,326 +0,0 @@ -#!/usr/bin/env python3 - -"""Build `demo.rerun.io`.""" -from __future__ import annotations - -import argparse -import html.parser -import http.server -import json -import os -import shutil -import subprocess -import threading -from functools import partial -from io import BytesIO -from pathlib import Path -from typing import Any - -import frontmatter -import requests -from jinja2 import Template -from PIL import Image - - -def measure_thumbnail(url: str) -> Any: - """Downloads `url` and returns its width and height.""" - response = requests.get(url) - response.raise_for_status() - image = Image.open(BytesIO(response.content)) - return image.size - - -# https://stackoverflow.com/a/7778368 -class HTMLTextExtractor(html.parser.HTMLParser): - def __init__(self) -> None: - super().__init__() - self.result: list[Any] = [] - - def handle_data(self, d: Any) -> None: - self.result.append(d) - - def get_text(self) -> str: - return "".join(self.result) - - -def extract_text_from_html(html: str) -> str: - """ - Strips tags and unescapes entities from `html`. - - This is not a sanitizer, it should not be used on untrusted input. - """ - extractor = HTMLTextExtractor() - extractor.feed(html) - return extractor.get_text() - - -def run( - args: list[str], *, env: dict[str, str] | None = None, timeout: int | None = None, cwd: str | None = None -) -> None: - print(f"> {subprocess.list2cmdline(args)}") - result = subprocess.run(args, env=env, cwd=cwd, timeout=timeout, check=False, capture_output=True, text=True) - assert ( - result.returncode == 0 - ), f"{subprocess.list2cmdline(args)} failed with exit-code {result.returncode}. Output:\n{result.stdout}\n{result.stderr}" - - -class Example: - def __init__( - self, - name: str, - commit: str, - build_args: list[str], - ): - readme_path = Path("examples/python", name, "README.md") - if readme_path.exists(): - readme = frontmatter.loads(readme_path.read_text()) - else: - readme = frontmatter.Post(content="") - - thumbnail_url = readme.get("thumbnail") - if thumbnail_url: - width, height = measure_thumbnail(thumbnail_url) - thumbnail = { - "url": thumbnail_url, - "width": width, - "height": height, - } - else: - thumbnail = None - - self.path = os.path.join("examples/python", name, "main.py") - self.name = name - self.title = readme.get("title") - self.description = readme.get("description") - self.summary = readme.get("summary") - self.tags = readme.get("tags", []) - self.demo_url = f"https://demo.rerun.io/commit/{commit}/examples/{name}/" - self.rrd_url = f"https://demo.rerun.io/commit/{commit}/examples/{name}/data.rrd" - self.source_url = f"https://github.com/rerun-io/rerun/tree/{commit}/examples/python/{name}/main.py" - self.thumbnail = thumbnail - self.build_args = build_args - self.description_html = "".join([f"

{segment}

" for segment in self.description.split("\n\n")]) - - def save(self) -> None: - in_path = os.path.abspath(self.path) - out_dir = f"{BASE_PATH}/examples/{self.name}" - - os.makedirs(out_dir, exist_ok=True) - rrd_path = os.path.join(out_dir, "data.rrd") - print(f"Running {self.name}, outputting to {rrd_path}") - - args = [ - "python3", - in_path, - f"--save={rrd_path}", - ] - - # Configure flushing so that: - # * the resulting file size is deterministic - # * the file is chunked into small batches for better streaming - env = {**os.environ, "RERUN_FLUSH_TICK_SECS": "1000000000", "RERUN_FLUSH_NUM_BYTES": str(128 * 1024)} - run(args + self.build_args, env=env) - print(f"{rrd_path}: {os.path.getsize(rrd_path) / (1024 * 1024):.1f} MiB") - - def supports_save(self) -> bool: - with open(self.path) as f: - return "script_add_args" in f.read() - - -def copy_static_assets(examples: list[Example]) -> None: - # copy root - src = os.path.join(SCRIPT_PATH, "demo_assets/static") - dst = BASE_PATH - print(f"\nCopying static assets from {src} to {dst}") - shutil.copytree(src, dst, dirs_exist_ok=True) - - # copy examples - for example in examples: - src = os.path.join(SCRIPT_PATH, "demo_assets/static") - dst = os.path.join(BASE_PATH, f"examples/{example.name}") - shutil.copytree( - src, - dst, - dirs_exist_ok=True, - ignore=shutil.ignore_patterns("index.html"), - ) - - -def build_python_sdk() -> None: - print("Building Python SDK…") - run( - [ - "maturin", - "develop", - "--manifest-path", - "rerun_py/Cargo.toml", - '--extras="tests"', - "--quiet", - ] - ) - - -def build_wasm() -> None: - print("") - run(["cargo", "r", "-p", "re_build_web_viewer", "--", "--release"]) - - -def copy_wasm(examples: list[Example]) -> None: - files = ["re_viewer_bg.wasm", "re_viewer.js"] - for example in examples: - for file in files: - shutil.copyfile( - os.path.join("web_viewer", file), - os.path.join(BASE_PATH, f"examples/{example.name}", file), - ) - - -def collect_examples() -> list[Example]: - commit = os.environ.get("COMMIT_HASH") or "main" - print(f"Commit hash: {commit}") - examples = [] - for name in EXAMPLES.keys(): - example = Example( - name, - commit=commit, - build_args=EXAMPLES[name]["build_args"], - ) - assert example.supports_save(), f'Example "{name}" does not support saving' - examples.append(example) - - return examples - - -def save_examples_rrd(examples: list[Example]) -> None: - print("\nSaving examples as .rrd…") - - print("") - for example in examples: - example.save() - print("") - - -def render_examples(examples: list[Example]) -> None: - print("Rendering examples") - - template_path = os.path.join(SCRIPT_PATH, "demo_assets/templates/example.html") - with open(template_path) as f: - template = Template(f.read()) - - for example in examples: - index_path = f"{BASE_PATH}/examples/{example.name}/index.html" - print(f"{example.name} -> {index_path}") - with open(index_path, "w") as f: - f.write(template.render(example=example, examples=examples)) - - -def render_manifest(examples: list[Example]) -> None: - print("Rendering index") - - index = [] - for example in examples: - index.append( - { - "name": example.name, - "title": example.title, - "description": example.description, - "tags": example.tags, - "demo_url": example.demo_url, - "rrd_url": example.rrd_url, - "thumbnail": example.thumbnail, - } - ) - - index_dir = Path(BASE_PATH) / "examples" - index_dir.mkdir(parents=True, exist_ok=True) - index_path = index_dir / "manifest.json" - index_path.write_text(json.dumps(index)) - - -def serve_files() -> None: - def serve() -> None: - print("\nServing examples at http://0.0.0.0:8080/") - server = http.server.HTTPServer( - server_address=("0.0.0.0", 8080), - RequestHandlerClass=partial( - http.server.SimpleHTTPRequestHandler, - directory=BASE_PATH, - ), - ) - server.serve_forever() - - threading.Thread(target=serve, daemon=True).start() - - -def main() -> None: - parser = argparse.ArgumentParser(description="Build and/or serve `demo.rerun.io`") - parser.add_argument( - "--serve", - action="store_true", - help="Serve the app on this port after building [default: 8080]", - ) - - parser.add_argument("--skip-build", action="store_true", help="Skip building the Python SDK and web viewer Wasm.") - parser.add_argument("--skip-examples", action="store_true", help="Skip running the examples.") - - args = parser.parse_args() - - if not args.skip_build: - build_python_sdk() - build_wasm() - - examples = collect_examples() - assert len(examples) > 0, "No examples found" - - if not args.skip_examples: - shutil.rmtree(f"{BASE_PATH}/examples", ignore_errors=True) - render_manifest(examples) - save_examples_rrd(examples) - - render_examples(examples) - copy_static_assets(examples) - copy_wasm(examples) - - if args.serve: - serve_files() - - while True: - try: - print("Press enter to reload static files") - input() - render_examples(examples) - copy_static_assets(examples) - copy_wasm(examples) - except KeyboardInterrupt: - break - - -BASE_PATH = "web_demo" -SCRIPT_PATH = os.path.dirname(os.path.relpath(__file__)) -# When adding examples, add their requirements to `requirements-web-demo.txt` -EXAMPLES: dict[str, Any] = { - "arkit_scenes": { - "build_args": [], - }, - "structure_from_motion": { - "build_args": ["--dataset=colmap_fiat", "--resize=800x600"], - }, - "dicom_mri": { - "build_args": [], - }, - "human_pose_tracking": { - "build_args": [], - }, - "plots": { - "build_args": [], - }, - "detect_and_track_objects": { - "build_args": [], - }, - "dna": { - "build_args": [], - }, -} - -if __name__ == "__main__": - main() diff --git a/scripts/ci/demo_assets/static/caret-down.svg b/scripts/ci/demo_assets/static/caret-down.svg deleted file mode 100644 index f14b63e5e4e6..000000000000 --- a/scripts/ci/demo_assets/static/caret-down.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/scripts/ci/demo_assets/static/caret-right.svg b/scripts/ci/demo_assets/static/caret-right.svg deleted file mode 100644 index 2f01ce021bd8..000000000000 --- a/scripts/ci/demo_assets/static/caret-right.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/scripts/ci/demo_assets/static/favicon.svg b/scripts/ci/demo_assets/static/favicon.svg deleted file mode 100644 index 4b48dd8c8c69..000000000000 --- a/scripts/ci/demo_assets/static/favicon.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/scripts/ci/demo_assets/static/github-mark-white.svg b/scripts/ci/demo_assets/static/github-mark-white.svg deleted file mode 100644 index 2cee3ca7accb..000000000000 --- a/scripts/ci/demo_assets/static/github-mark-white.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/scripts/ci/demo_assets/static/index.css b/scripts/ci/demo_assets/static/index.css deleted file mode 100644 index 7fd5c8d04535..000000000000 --- a/scripts/ci/demo_assets/static/index.css +++ /dev/null @@ -1,312 +0,0 @@ -html { - /* Remove touch delay: */ - touch-action: manipulation; -} - -body { - background: #0d1011; -} - -/* Allow canvas to fill entire web page: */ -html, -body { - overflow: hidden; - margin: 0 !important; - padding: 0 !important; - height: 100%; - width: 100%; -} - -/* Position canvas in center-top: */ -canvas { - margin-right: auto; - margin-left: auto; - display: block; - position: absolute; - top: 0%; - left: 50%; - transform: translate(-50%, 0%); - /* canvas must be on top when visible */ - z-index: 1000; -} - -* { - font-family: "Inter", sans-serif; - color: #cad8de; -} - -/* Match the Rerun header bar. */ -.header { - width: 100%; - height: 44px; - /* Actual value from Rerun Viewer */ - background: #141414; -} - -/* Create a container filling the remaining space. */ -.container { - position: absolute; - height: calc(100vh - 44px); - width: 100vw; -} - -/* Centered div inside the container. */ -.centered { - margin-right: auto; - margin-left: auto; - display: block; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - text-align: center; -} - -/* Rerun styling for normal text. */ -p { - /*Gray-775*/ - color: #cad8de; - letter-spacing: -0.15px; - font-weight: 500; -} - -/* Rerun styling for strong text. Matches `TextStyle::Heading`. */ -.strong { - /*Gray-775*/ - color: #cad8de; - /* Match current rerun header value */ - font-size: 16px; -} - -/* Rerun styling for subdued text.*/ -.subdued { - /*Gray-550*/ - color: #7d8c92; - /* Larger subdued size to match current rerun font */ - font-size: 12px; - letter-spacing: -0.12px; -} - -pre { - /*Gray-550*/ - color: #7d8c92; - font-size: 10px; - letter-spacing: -0.12px; -} - -a .button { - display: inline-block; - background: white; - color: black; - padding: 0.75rem 1rem; - border-radius: 8px; - text-decoration: none; - font-weight: 500; -} - -/* Transition to hidden */ -.hidden { - opacity: 0; - transition: opacity 0.2s ease-out; - visibility: hidden; -} - -/* Transition to visible */ -.visible { - opacity: 100; - transition: opacity 0.2s ease-in; - visibility: visible; -} - -.demo_header { - z-index: 1100; - position: absolute; - transform: translate(-50%, 0); - left: 50%; - height: 44px; - - display: flex; - flex-direction: row; - gap: 4px; - - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.no-select { - user-select: none; -} - -.examples { - position: relative; - top: 11px; -} - -.example-description { - margin-top: 6px; - height: 40px; - border: none; - border-radius: 33%; -} - -.example-description:hover > .example-description-body { - display: flex; -} - -.example-description:hover > .example-description-icon { - background: #404040; - border: none; - border-radius: 5px; -} - -.example-description-icon { - display: flex; - justify-content: center; - margin: 4px; - padding: 2px; - width: 20px; - height: 20px; - user-select: none; -} - -.example-description-body { - display: none; - - flex-direction: column; - gap: 8px; - - position: absolute; - top: 100%; - - background: #262626; - border: none; - border-radius: 6px; - padding: 12px; - - font-size: 13px; - line-height: 1.33; - letter-spacing: 0; - - width: 280px; -} - -.example-description-body > p { - margin: 0; -} - -a.icon-link { - margin: 5px; - padding: 5px; - width: 24.5px; - height: 24px; -} - -a.icon-link:hover { - background: #404040; - border: none; - border-radius: 50%; -} - -img.icon { - max-height: 100%; -} - -.dropdown { - position: relative; -} - -.dropdown-title { - display: flex; - gap: 2px; - user-select: none; - cursor: pointer; - - background: #141414; - border: none; - border-radius: 6px; - padding: 2px 5px 2px 8px; - - font-style: normal; - font-weight: 435; - font-size: 14px; - line-height: 16px; -} - -.dropdown-title > img { - width: 16px; - height: 16px; -} - -.dropdown-title:hover { - background: #404040; -} - -.dropdown-title:active { - background: #404040; -} - -.dropdown-body { - display: none; - - flex-direction: column; - gap: 3px; - - position: absolute; - top: 100%; - left: 0; - - background: #262626; - border: none; - border-radius: 6px; - padding: 6px; - - user-select: none; - font-size: 12px; -} - -.dropdown-body.visible { - display: flex; -} - -.dropdown-entry { - padding: 2px 5px; - border: none; - border-radius: 6px; - font-size: 13px; - display: flex; - justify-content: space-between; - white-space: nowrap; - overflow: hidden; -} - -.dropdown-entry:hover { - background: #404040; -} - -a.flat-link { - text-decoration: none; -} - -.centered { - margin-right: auto; - margin-left: auto; - display: block; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - color: #cad8de; - font-size: 24px; - font-family: Ubuntu-Light, Helvetica, sans-serif; - text-align: center; -} - -a.button { - display: inline-block; - background: white; - color: black; - padding: 0.75rem 1rem; - border-radius: 8px; - text-decoration: none; - font-weight: 500; -} diff --git a/scripts/ci/demo_assets/static/index.html b/scripts/ci/demo_assets/static/index.html deleted file mode 100644 index 81492fe61cf5..000000000000 --- a/scripts/ci/demo_assets/static/index.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - Rerun Viewer - - - - -
-

Loading…

-
-
- - - - - - - - diff --git a/scripts/ci/demo_assets/static/index.js b/scripts/ci/demo_assets/static/index.js deleted file mode 100644 index b5e42de2f398..000000000000 --- a/scripts/ci/demo_assets/static/index.js +++ /dev/null @@ -1,251 +0,0 @@ -function show_center_html(html) { - center_text_elem = document.getElementById("center_text"); - center_text_elem.innerHTML = html; - center_text_elem.classList.remove("hidden"); - center_text_elem.classList.add("visible"); -} -function hide_center_html(html) { - center_text_elem = document.getElementById("center_text"); - center_text_elem.innerHTML = html; - center_text_elem.classList.remove("visible"); - center_text_elem.classList.add("hidden"); -} -function show_canvas(html) { - canvas_elem = document.getElementById("the_canvas_id"); - canvas_elem.classList.remove("hidden"); - canvas_elem.classList.add("visible"); - demo_header_elem = document.getElementById("header_bar"); - demo_header_elem.classList.add("visible"); - demo_header_elem.classList.remove("hidden"); -} -function hide_canvas(html) { - canvas_elem = document.getElementById("the_canvas_id"); - canvas_elem.classList.remove("visible"); - canvas_elem.classList.add("hidden"); - demo_header_elem = document.getElementById("header_bar"); - demo_header_elem.classList.add("hidden"); - demo_header_elem.classList.remove("visible"); -} - -// On mobile platforms show a warning, but provide a link to try anyways -if ( - /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( - navigator.userAgent, - ) -) { - show_center_html(` -

- Rerun is not yet supported on mobile browsers. -

-

- Try anyways -

`); - document - .querySelector("#try_anyways") - .addEventListener("click", function (event) { - event.preventDefault(); - load_wasm(); - }); -} else { - load_wasm(); -} - -function load_wasm() { - // We'll defer our execution until the wasm is ready to go. - // Here we tell bindgen the path to the wasm file so it can start - // initialization and return to us a promise when it's done. - - document.getElementById("center_text").innerHTML = ` -

- Loading Application Bundle… -

-

-

`; - - const status_element = document.getElementById("status"); - function progress({ loaded, total_bytes }) { - if (total_bytes != null) { - status_element.innerHTML = - Math.round(Math.min((loaded / total_bytes) * 100, 100)) + "%"; - } else { - status_element.innerHTML = (loaded / (1024 * 1024)).toFixed(1) + "MiB"; - } - } - - var timeoutId = setTimeout(function () { - document.getElementById("center_text").classList.remove("hidden"); - document.getElementById("center_text").classList.add("visible"); - }, 1500); - - async function wasm_with_progress() { - const response = await fetch("./re_viewer_bg.wasm"); - // Use the uncompressed size - var content_length; - var content_multiplier = 1; - // If the content is gzip encoded, try to get the uncompressed size. - if (response.headers.get("content-encoding") == "gzip") { - content_length = response.headers.get("x-goog-meta-uncompressed-size"); - - // If the uncompressed size wasn't found 3 seems to be a very good approximation - if (content_length == null) { - content_length = response.headers.get("content-length"); - content_multiplier = 3; - } - } else { - content_length = response.headers.get("content-length"); - } - - const total_bytes = parseInt(content_length, 10) * content_multiplier; - let loaded = 0; - - const res = new Response( - new ReadableStream({ - async start(controller) { - const reader = response.body.getReader(); - for (;;) { - const { done, value } = await reader.read(); - if (done) break; - loaded += value.byteLength; - progress({ loaded, total_bytes }); - controller.enqueue(value); - } - controller.close(); - }, - }), - { - status: response.status, - statusText: response.statusText, - }, - ); - - for (const [key, value] of response.headers.entries()) { - res.headers.set(key, value); - } - - wasm_bindgen(res) - .then(() => (clearTimeout(timeoutId), on_wasm_loaded())) - .catch(on_wasm_error); - } - - wasm_with_progress(); -} - -function on_wasm_loaded() { - window.set_email = (value) => wasm_bindgen.set_email(value); - - // WebGPU version is currently only supported on browsers with WebGPU support, there is no dynamic fallback to WebGL. - if (wasm_bindgen.is_webgpu_build() && typeof navigator.gpu === "undefined") { - console.debug( - "`navigator.gpu` is undefined. This indicates lack of WebGPU support.", - ); - show_center_html(` -

- Missing WebGPU support. -

-

- This version of Rerun requires WebGPU support which is not available in your browser. - Either try a different browser or use the WebGL version of Rerun. -

`); - return; - } - - console.debug("Wasm loaded. Starting app…"); - - let handle = new wasm_bindgen.WebHandle(); - - function check_for_panic() { - if (handle.has_panicked()) { - console.error("Rerun has crashed"); - - document.getElementById("the_canvas_id").remove(); - - show_center_html(` -

- Rerun has crashed. -

-
${handle.panic_message()}
-

- See the console for details. -

-

- Reload the page to try again. -

`); - } else { - let delay_ms = 1000; - setTimeout(check_for_panic, delay_ms); - } - } - - check_for_panic(); - - let url = determine_url(); - handle.start("the_canvas_id", url).then(on_app_started).catch(on_wasm_error); -} - -function on_app_started(handle) { - // Call `handle.destroy()` to stop. Uncomment to quick result: - // setTimeout(() => { handle.destroy(); handle.free()) }, 2000) - - console.debug("App started."); - - hide_center_html(); - show_canvas(); - - if (window.location !== window.parent.location) { - window.parent.postMessage("READY", "*"); - } -} - -function determine_url() { - const base = window.location.pathname.endsWith("/") - ? window.location.pathname.slice(0, -1) - : window.location.pathname; - return base + "/data.rrd"; -} - -function on_wasm_error(error) { - console.error("Failed to start: " + error); - - let render_backend_name = "WebGPU/WebGL"; - try { - render_backend_name = wasm_bindgen.is_webgpu_build() ? "WebGPU" : "WebGL"; - } catch (e) { - // loading the wasm probably failed. - } - - hide_canvas(); - show_center_html(` -

- An error occurred during loading: -

-

- ${error} -

-

- Make sure you use a modern browser with ${render_backend_name} and Wasm enabled. -

`); -} - -// open/close dropdown -document.querySelector("#examples").addEventListener("click", () => { - const body = document.querySelector(".dropdown-body"); - if (!body) return; - if (body.classList.contains("visible")) { - body.classList.remove("visible"); - } else { - body.classList.add("visible"); - } -}); - -// close dropdowns by clicking outside of it -document.body.addEventListener("click", (event) => { - const body = document.querySelector(".dropdown-body"); - if (!body) return; - - const is_dropdown = (element) => - element instanceof HTMLElement && element.classList.contains("dropdown"); - - if (!event.composedPath().find(is_dropdown)) { - body.classList.remove("visible"); - } -}); diff --git a/scripts/ci/demo_assets/static/manifest.json b/scripts/ci/demo_assets/static/manifest.json deleted file mode 100644 index 5f31d7b55c51..000000000000 --- a/scripts/ci/demo_assets/static/manifest.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "Rerun Viewer", - "short_name": "rerun-viewer-pwa", - "icons": [ - { - "src": "./icon-256.png", - "sizes": "256x256", - "type": "image/png" - } - ], - "lang": "en-US", - "start_url": "./index.html", - "display": "standalone", - "background_color": "white", - "theme_color": "white" -} diff --git a/scripts/ci/demo_assets/static/sw.js b/scripts/ci/demo_assets/static/sw.js deleted file mode 100644 index 420648dbc993..000000000000 --- a/scripts/ci/demo_assets/static/sw.js +++ /dev/null @@ -1,27 +0,0 @@ -var cacheName = "rerun-viewer-pwa"; -var filesToCache = [ - "./", - "./index.html", - "./index.js", - "./index.css", - "./re_viewer.js", - "./re_viewer_bg.wasm", -]; - -/* Start the service worker and cache all of the app's content */ -self.addEventListener("install", function (e) { - e.waitUntil( - caches.open(cacheName).then(function (cache) { - return cache.addAll(filesToCache); - }), - ); -}); - -/* Serve cached content when offline */ -self.addEventListener("fetch", function (e) { - e.respondWith( - caches.match(e.request).then(function (response) { - return response || fetch(e.request); - }), - ); -}); diff --git a/scripts/ci/demo_assets/templates/example.html b/scripts/ci/demo_assets/templates/example.html deleted file mode 100644 index 96e53d9e297f..000000000000 --- a/scripts/ci/demo_assets/templates/example.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - Rerun Viewer - - - - - - - -
- -
-
- -
- - - - - - - - - - - - - - diff --git a/scripts/screenshot_compare/build_screenshot_compare.py b/scripts/screenshot_compare/build_screenshot_compare.py index 92580d657e6d..e2f039718f93 100755 --- a/scripts/screenshot_compare/build_screenshot_compare.py +++ b/scripts/screenshot_compare/build_screenshot_compare.py @@ -159,14 +159,14 @@ def build_demo_examples() -> None: def collect_demo_examples() -> Iterable[Example]: - web_demo_example_dir = RERUN_DIR / "example_data" - assert web_demo_example_dir.exists(), "Web demos have not been built yet." + example_dir = RERUN_DIR / "example_data" + assert example_dir.exists(), "Examples have not been built yet." - manifest = json.loads((web_demo_example_dir / "examples_manifest.json").read_text()) + manifest = json.loads((example_dir / "examples_manifest.json").read_text()) for example in manifest: name = example["name"] - rrd = web_demo_example_dir / f"{name}.rrd" + rrd = example_dir / f"{name}.rrd" assert rrd.exists(), f"Missing {rrd} for {name}" yield Example(