mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
Fix regressions: Transferable flatbuffers (#221)
* Add geometry index again * Switch to info level for run config * Add setting for present_mode * Remove unused file * Adjust web to new message * Update package-lock.json * One of the first working versions with a large buffer * Add features to fix builds * Switch to flatbuffers for data passing * Cleanup and move entries to wasm_entries * Install protobuf and flatbuffers * Fix windows CI * Fix clippy errors and warnings for generated code
This commit is contained in:
parent
1b73ad5908
commit
9496ef0e71
2
.github/actions/cargo-install/action.yml
vendored
2
.github/actions/cargo-install/action.yml
vendored
@ -47,7 +47,7 @@ runs:
|
||||
INSTALL_PATH="~/.binstall/"
|
||||
mkdir -p "$INSTALL_PATH"
|
||||
if [[ $FILE == *"zip"* ]]; then
|
||||
unzip /tmp/binstall.bin -d "$INSTALL_PATH"
|
||||
unzip -o /tmp/binstall.bin -d "$INSTALL_PATH"
|
||||
elif [[ $FILE == *"tgz"* ]]; then
|
||||
tar xf /tmp/binstall.bin -C "$INSTALL_PATH"
|
||||
else
|
||||
|
||||
17
.github/actions/install-flatbuffers/action.yml
vendored
Normal file
17
.github/actions/install-flatbuffers/action.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
name: install-flatbuffers
|
||||
description: Install flatbuffers
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Install flatbuffers
|
||||
shell: bash
|
||||
run: |
|
||||
git clone https://github.com/google/flatbuffers.git
|
||||
cd flatbuffers
|
||||
git checkout v22.12.06
|
||||
cmake -G "Unix Makefiles"
|
||||
make
|
||||
./flattests
|
||||
sudo make install
|
||||
flatc --version
|
||||
32
.github/actions/install-system-dependencies/action.yml
vendored
Normal file
32
.github/actions/install-system-dependencies/action.yml
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
name: install-system-dependencies
|
||||
description: Install system dependencies
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Install System Dependencies (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: bash
|
||||
run: pacman -S --noconfirm mingw-w64-x86_64-protobuf
|
||||
- name: Install System Dependencies (Ubuntu)
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get install -y \
|
||||
protobuf-compiler \
|
||||
libwayland-dev libxkbcommon-dev # Required for winit
|
||||
- name: Install System Dependencies (Ubuntu)
|
||||
if: runner.os == 'macOS'
|
||||
shell: bash
|
||||
run: brew install protobuf
|
||||
|
||||
- name: Check Dependencies
|
||||
if: runner.os != 'Windows'
|
||||
shell: bash
|
||||
run: |
|
||||
protoc --version
|
||||
- name: Check Dependencies
|
||||
if: runner.os == 'Windows'
|
||||
shell: powershell
|
||||
run: |
|
||||
protoc.exe --version
|
||||
3
.github/workflows/build-deploy-docs.yml
vendored
3
.github/workflows/build-deploy-docs.yml
vendored
@ -21,8 +21,7 @@ jobs:
|
||||
with:
|
||||
name: mdbook
|
||||
- name: Install Dependencies
|
||||
shell: bash
|
||||
run: sudo apt-get install -y libwayland-dev libxkbcommon-dev # Required for winit
|
||||
uses: ./.github/actions/install-system-dependencies
|
||||
- name: Build
|
||||
working-directory: docs
|
||||
shell: bash
|
||||
|
||||
3
.github/workflows/demo-linux.yml
vendored
3
.github/workflows/demo-linux.yml
vendored
@ -14,8 +14,7 @@ jobs:
|
||||
with:
|
||||
targets: x86_64-unknown-linux-gnu
|
||||
- name: Install Dependencies
|
||||
shell: bash
|
||||
run: sudo apt-get install -y libwayland-dev libxkbcommon-dev # Required for winit
|
||||
uses: ./.github/actions/install-system-dependencies
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: cargo build -p maplibre-demo --release --target x86_64-unknown-linux-gnu
|
||||
|
||||
2
.github/workflows/demo-macos.yml
vendored
2
.github/workflows/demo-macos.yml
vendored
@ -13,6 +13,8 @@ jobs:
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
targets: x86_64-apple-darwin
|
||||
- name: Install Dependencies
|
||||
uses: ./.github/actions/install-system-dependencies
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: cd apple/xcode && xcodebuild -scheme "example (macOS)" build CODE_SIGNING_ALLOWED=NO MACOSX_DEPLOYMENT_TARGET=10.9 -derivedDataPath build
|
||||
|
||||
6
.github/workflows/demo-windows.yml
vendored
6
.github/workflows/demo-windows.yml
vendored
@ -10,7 +10,9 @@ jobs:
|
||||
steps:
|
||||
- name: Switch to msys2
|
||||
shell: powershell
|
||||
run: echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
run: |
|
||||
echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
echo "C:\msys64\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
- name: Install mysys2 dependencies
|
||||
shell: powershell
|
||||
run: pacman -S --noconfirm unzip
|
||||
@ -22,6 +24,8 @@ jobs:
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
targets: x86_64-pc-windows-msvc
|
||||
- name: Install Dependencies
|
||||
uses: ./.github/actions/install-system-dependencies
|
||||
- name: Build
|
||||
shell: powershell
|
||||
run: cargo build -p maplibre-demo --release --target x86_64-pc-windows-msvc
|
||||
|
||||
2
.github/workflows/library-android.yml
vendored
2
.github/workflows/library-android.yml
vendored
@ -14,6 +14,8 @@ jobs:
|
||||
with:
|
||||
nightly: true
|
||||
targets: x86_64-linux-android aarch64-linux-android i686-linux-android
|
||||
- name: Install Dependencies
|
||||
uses: ./.github/actions/install-system-dependencies
|
||||
- name: Set NDK Version
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
5
.github/workflows/library-apple.yml
vendored
5
.github/workflows/library-apple.yml
vendored
@ -3,9 +3,6 @@ name: Build apple library
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
library-apple:
|
||||
runs-on: macos-12
|
||||
@ -37,6 +34,8 @@ jobs:
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
targets: ${{ matrix.target }} ${{ matrix.fat-target }}
|
||||
- name: Install Dependencies
|
||||
uses: ./.github/actions/install-system-dependencies
|
||||
- name: Swift Version
|
||||
shell: bash
|
||||
run: swift --version
|
||||
|
||||
11
.github/workflows/library-web.yml
vendored
11
.github/workflows/library-web.yml
vendored
@ -32,11 +32,10 @@ jobs:
|
||||
with:
|
||||
nightly: true
|
||||
targets: wasm32-unknown-unknown
|
||||
- name: Install rust sources (build-std)
|
||||
if: inputs.multithreaded
|
||||
shell: bash
|
||||
run: |
|
||||
just nightly-install-src
|
||||
- name: Install Dependencies
|
||||
uses: ./.github/actions/install-system-dependencies
|
||||
- name: Install flatbuffers
|
||||
uses: ./.github/actions/install-flatbuffers
|
||||
- name: Install wasm-bindgen
|
||||
uses: ./.github/actions/cargo-install
|
||||
# Install wasm-bindgen with test runner
|
||||
@ -49,7 +48,7 @@ jobs:
|
||||
- name: Build demo
|
||||
shell: bash
|
||||
run: just web-demo build
|
||||
- name: Check
|
||||
- name: Check # TODO: Also check here multithreaded configurations
|
||||
shell: bash
|
||||
run: just nightly-check web wasm32-unknown-unknown ${{ inputs.webgl && 'web-webgl' || '""' }}
|
||||
- name: Test
|
||||
|
||||
2
.github/workflows/run-benchmarks.yml
vendored
2
.github/workflows/run-benchmarks.yml
vendored
@ -13,6 +13,8 @@ jobs:
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
targets: x86_64-unknown-linux-gnu
|
||||
- name: Install Dependencies
|
||||
uses: ./.github/actions/install-system-dependencies
|
||||
- name: Install GPU Drivers
|
||||
uses: ./.github/actions/install-driver
|
||||
- name: Download test data
|
||||
|
||||
2
.github/workflows/run-tests.yml
vendored
2
.github/workflows/run-tests.yml
vendored
@ -13,6 +13,8 @@ jobs:
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
targets: x86_64-unknown-linux-gnu
|
||||
- name: Install Dependencies
|
||||
uses: ./.github/actions/install-system-dependencies
|
||||
- name: Install GPU Drivers
|
||||
uses: ./.github/actions/install-driver
|
||||
- name: Test Vulkan
|
||||
|
||||
5
justfile
5
justfile
@ -32,13 +32,12 @@ nightly-override-toolchain: nightly-toolchain
|
||||
|
||||
nightly-targets *FLAGS: nightly-toolchain
|
||||
rustup toolchain install $NIGHTLY_TOOLCHAIN --target {{FLAGS}}
|
||||
# We sometimes build the stdlib with nightly
|
||||
rustup component add rust-src --toolchain $NIGHTLY_TOOLCHAIN
|
||||
|
||||
nightly-install-rustfmt: nightly-toolchain
|
||||
rustup component add rustfmt --toolchain $NIGHTLY_TOOLCHAIN
|
||||
|
||||
nightly-install-src: nightly-toolchain
|
||||
rustup component add rust-src --toolchain $NIGHTLY_TOOLCHAIN
|
||||
|
||||
nightly-install-clippy: stable-toolchain
|
||||
rustup component add clippy --toolchain $NIGHTLY_TOOLCHAIN
|
||||
|
||||
|
||||
@ -48,6 +48,10 @@ impl Processable for IndexLayer {
|
||||
layer.process(&mut index).unwrap();
|
||||
}
|
||||
|
||||
for layer in &mut tile.layers {
|
||||
layer.process(&mut index).unwrap();
|
||||
}
|
||||
|
||||
context
|
||||
.processor_mut()
|
||||
.layer_indexing_finished(&tile_request.coords, index.get_geometries())?;
|
||||
|
||||
@ -111,7 +111,8 @@ impl TileRepository {
|
||||
{
|
||||
match entry {
|
||||
btree_map::Entry::Vacant(_entry) => {
|
||||
panic!("Can not add a tessellated layer if no request has been started before.")
|
||||
panic!("Can not add a tessellated layer at {} if no request has been started before. \
|
||||
We might received a tile which was not requested.", layer.get_coords())
|
||||
}
|
||||
btree_map::Entry::Occupied(mut entry) => {
|
||||
entry.get_mut().layers.push(layer);
|
||||
|
||||
@ -8,34 +8,45 @@ use crate::{
|
||||
};
|
||||
|
||||
pub trait TileTessellated: Send {
|
||||
fn new(coords: WorldTileCoords) -> Self;
|
||||
fn build_from(coords: WorldTileCoords) -> Self
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
fn coords(&self) -> &WorldTileCoords;
|
||||
fn coords(&self) -> WorldTileCoords;
|
||||
}
|
||||
|
||||
pub trait UnavailableLayer: Send {
|
||||
fn new(coords: WorldTileCoords, layer_name: String) -> Self;
|
||||
pub trait LayerUnavailable: Send {
|
||||
fn build_from(coords: WorldTileCoords, layer_name: String) -> Self
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
fn coords(&self) -> &WorldTileCoords;
|
||||
fn coords(&self) -> WorldTileCoords;
|
||||
fn layer_name(&self) -> &str;
|
||||
|
||||
fn to_stored_layer(self) -> StoredLayer;
|
||||
}
|
||||
|
||||
pub trait TessellatedLayer: Send {
|
||||
fn new(
|
||||
pub trait LayerTessellated: Send {
|
||||
fn build_from(
|
||||
coords: WorldTileCoords,
|
||||
buffer: OverAlignedVertexBuffer<ShaderVertex, IndexDataType>,
|
||||
feature_indices: Vec<u32>,
|
||||
layer_data: Layer,
|
||||
) -> Self;
|
||||
) -> Self
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
fn coords(&self) -> &WorldTileCoords;
|
||||
fn coords(&self) -> WorldTileCoords;
|
||||
|
||||
fn to_stored_layer(self) -> StoredLayer;
|
||||
}
|
||||
|
||||
pub trait IndexedLayer: Send + From<(WorldTileCoords, TileIndex)> {
|
||||
fn coords(&self) -> &WorldTileCoords;
|
||||
pub trait LayerIndexed: Send {
|
||||
fn build_from(coords: WorldTileCoords, index: TileIndex) -> Self
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
fn coords(&self) -> WorldTileCoords;
|
||||
|
||||
fn to_tile_index(self) -> TileIndex;
|
||||
}
|
||||
@ -45,12 +56,12 @@ pub struct DefaultTileTessellated {
|
||||
}
|
||||
|
||||
impl TileTessellated for DefaultTileTessellated {
|
||||
fn new(coords: WorldTileCoords) -> Self {
|
||||
fn build_from(coords: WorldTileCoords) -> Self {
|
||||
Self { coords }
|
||||
}
|
||||
|
||||
fn coords(&self) -> &WorldTileCoords {
|
||||
&self.coords
|
||||
fn coords(&self) -> WorldTileCoords {
|
||||
self.coords
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,13 +70,17 @@ pub struct DefaultLayerUnavailable {
|
||||
pub layer_name: String,
|
||||
}
|
||||
|
||||
impl UnavailableLayer for DefaultLayerUnavailable {
|
||||
fn new(coords: WorldTileCoords, layer_name: String) -> Self {
|
||||
impl LayerUnavailable for DefaultLayerUnavailable {
|
||||
fn build_from(coords: WorldTileCoords, layer_name: String) -> Self {
|
||||
Self { coords, layer_name }
|
||||
}
|
||||
|
||||
fn coords(&self) -> &WorldTileCoords {
|
||||
&self.coords
|
||||
fn coords(&self) -> WorldTileCoords {
|
||||
self.coords
|
||||
}
|
||||
|
||||
fn layer_name(&self) -> &str {
|
||||
&self.layer_name
|
||||
}
|
||||
|
||||
fn to_stored_layer(self) -> StoredLayer {
|
||||
@ -76,6 +91,7 @@ impl UnavailableLayer for DefaultLayerUnavailable {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DefaultLayerTesselated {
|
||||
pub coords: WorldTileCoords,
|
||||
pub buffer: OverAlignedVertexBuffer<ShaderVertex, IndexDataType>,
|
||||
@ -84,8 +100,8 @@ pub struct DefaultLayerTesselated {
|
||||
pub layer_data: Layer, // FIXME (perf): Introduce a better structure for this
|
||||
}
|
||||
|
||||
impl TessellatedLayer for DefaultLayerTesselated {
|
||||
fn new(
|
||||
impl LayerTessellated for DefaultLayerTesselated {
|
||||
fn build_from(
|
||||
coords: WorldTileCoords,
|
||||
buffer: OverAlignedVertexBuffer<ShaderVertex, IndexDataType>,
|
||||
feature_indices: Vec<u32>,
|
||||
@ -99,8 +115,8 @@ impl TessellatedLayer for DefaultLayerTesselated {
|
||||
}
|
||||
}
|
||||
|
||||
fn coords(&self) -> &WorldTileCoords {
|
||||
&self.coords
|
||||
fn coords(&self) -> WorldTileCoords {
|
||||
self.coords
|
||||
}
|
||||
|
||||
fn to_stored_layer(self) -> StoredLayer {
|
||||
@ -118,15 +134,13 @@ pub struct DefaultLayerIndexed {
|
||||
index: TileIndex,
|
||||
}
|
||||
|
||||
impl From<(WorldTileCoords, TileIndex)> for DefaultLayerIndexed {
|
||||
fn from((coords, index): (WorldTileCoords, TileIndex)) -> Self {
|
||||
impl LayerIndexed for DefaultLayerIndexed {
|
||||
fn build_from(coords: WorldTileCoords, index: TileIndex) -> Self {
|
||||
Self { coords, index }
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexedLayer for DefaultLayerIndexed {
|
||||
fn coords(&self) -> &WorldTileCoords {
|
||||
&self.coords
|
||||
fn coords(&self) -> WorldTileCoords {
|
||||
self.coords
|
||||
}
|
||||
|
||||
fn to_tile_index(self) -> TileIndex {
|
||||
@ -136,9 +150,9 @@ impl IndexedLayer for DefaultLayerIndexed {
|
||||
|
||||
pub trait Transferables: 'static {
|
||||
type TileTessellated: TileTessellated;
|
||||
type LayerUnavailable: UnavailableLayer;
|
||||
type LayerTessellated: TessellatedLayer;
|
||||
type LayerIndexed: IndexedLayer;
|
||||
type LayerUnavailable: LayerUnavailable;
|
||||
type LayerTessellated: LayerTessellated;
|
||||
type LayerIndexed: LayerIndexed;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
||||
@ -14,7 +14,9 @@ use crate::{
|
||||
geometry_index::{IndexedGeometry, TileIndex},
|
||||
pipeline::PipelineProcessor,
|
||||
source_client::HttpClient,
|
||||
transferables::{TessellatedLayer, TileTessellated, Transferables, UnavailableLayer},
|
||||
transferables::{
|
||||
LayerIndexed, LayerTessellated, LayerUnavailable, TileTessellated, Transferables,
|
||||
},
|
||||
},
|
||||
kernel::Kernel,
|
||||
render::ShaderVertex,
|
||||
@ -43,7 +45,9 @@ impl<'c, T: Transferables, HC: HttpClient, C: Context<T, HC>> PipelineProcessor
|
||||
{
|
||||
fn tile_finished(&mut self, coords: &WorldTileCoords) -> Result<(), Error> {
|
||||
self.context
|
||||
.send(Message::TileTessellated(T::TileTessellated::new(*coords)))
|
||||
.send(Message::TileTessellated(T::TileTessellated::build_from(
|
||||
*coords,
|
||||
)))
|
||||
}
|
||||
|
||||
fn layer_unavailable(
|
||||
@ -52,7 +56,7 @@ impl<'c, T: Transferables, HC: HttpClient, C: Context<T, HC>> PipelineProcessor
|
||||
layer_name: &str,
|
||||
) -> Result<(), Error> {
|
||||
self.context
|
||||
.send(Message::LayerUnavailable(T::LayerUnavailable::new(
|
||||
.send(Message::LayerUnavailable(T::LayerUnavailable::build_from(
|
||||
*coords,
|
||||
layer_name.to_owned(),
|
||||
)))
|
||||
@ -66,7 +70,7 @@ impl<'c, T: Transferables, HC: HttpClient, C: Context<T, HC>> PipelineProcessor
|
||||
layer_data: tile::Layer,
|
||||
) -> Result<(), Error> {
|
||||
self.context
|
||||
.send(Message::LayerTessellated(T::LayerTessellated::new(
|
||||
.send(Message::LayerTessellated(T::LayerTessellated::build_from(
|
||||
*coords,
|
||||
buffer,
|
||||
feature_indices,
|
||||
@ -80,9 +84,9 @@ impl<'c, T: Transferables, HC: HttpClient, C: Context<T, HC>> PipelineProcessor
|
||||
geometries: Vec<IndexedGeometry<f64>>,
|
||||
) -> Result<(), Error> {
|
||||
self.context
|
||||
.send(Message::LayerIndexed(T::LayerIndexed::from((
|
||||
.send(Message::LayerIndexed(T::LayerIndexed::build_from(
|
||||
*coords,
|
||||
TileIndex::Linear { list: geometries },
|
||||
))))
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ use crate::{
|
||||
io::{
|
||||
apc::{AsyncProcedureCall, Message},
|
||||
tile_repository::StoredLayer,
|
||||
transferables::{IndexedLayer, TessellatedLayer, TileTessellated, UnavailableLayer},
|
||||
transferables::{LayerIndexed, LayerTessellated, LayerUnavailable, TileTessellated},
|
||||
},
|
||||
kernel::Kernel,
|
||||
schedule::Stage,
|
||||
@ -46,7 +46,7 @@ impl<E: Environment> Stage for PopulateTileStore<E> {
|
||||
tracing::trace!("Tile at {} finished loading", coords);
|
||||
log::warn!("Tile at {} finished loading", coords);
|
||||
|
||||
tile_repository.mark_tile_succeeded(coords);
|
||||
tile_repository.mark_tile_succeeded(&coords);
|
||||
}
|
||||
// FIXME: deduplicate
|
||||
Message::LayerUnavailable(message) => {
|
||||
@ -77,7 +77,7 @@ impl<E: Environment> Stage for PopulateTileStore<E> {
|
||||
tile_repository.put_layer(layer);
|
||||
}
|
||||
Message::LayerIndexed(message) => {
|
||||
let coords = *message.coords();
|
||||
let coords = message.coords();
|
||||
|
||||
log::warn!("Layer index at {} reached main thread", coords);
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ use crate::{
|
||||
pipeline::{PipelineContext, Processable},
|
||||
tile_pipelines::build_vector_tile_pipeline,
|
||||
tile_repository::TileRepository,
|
||||
transferables::{Transferables, UnavailableLayer},
|
||||
transferables::{LayerUnavailable, Transferables},
|
||||
TileRequest,
|
||||
},
|
||||
kernel::Kernel,
|
||||
@ -96,7 +96,7 @@ pub fn schedule<
|
||||
context.send(
|
||||
Message::LayerUnavailable(<<E::AsyncProcedureCall as AsyncProcedureCall<
|
||||
E::HttpClient,
|
||||
>>::Transferables as Transferables>::LayerUnavailable::new(
|
||||
>>::Transferables as Transferables>::LayerUnavailable::build_from(
|
||||
input.coords,
|
||||
to_load.to_string(),
|
||||
)),
|
||||
|
||||
@ -57,14 +57,18 @@ impl<V, I> OverAlignedVertexBuffer<V, I> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_slices(vertices: &[V], indices: &[I], usable_indices: u32) -> Self
|
||||
pub fn from_iters<IV, II>(vertices: IV, indices: II, usable_indices: u32) -> Self
|
||||
where
|
||||
V: Copy,
|
||||
I: Copy,
|
||||
IV: IntoIterator<Item = V>,
|
||||
II: IntoIterator<Item = I>,
|
||||
IV::IntoIter: ExactSizeIterator,
|
||||
II::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let mut buffers = VertexBuffers::with_capacity(0, 0);
|
||||
buffers.vertices = Vec::from(vertices);
|
||||
buffers.indices = Vec::from(indices);
|
||||
let vertices = vertices.into_iter();
|
||||
let indices = indices.into_iter();
|
||||
let mut buffers = VertexBuffers::with_capacity(vertices.len(), indices.len());
|
||||
buffers.vertices.extend(vertices);
|
||||
buffers.indices.extend(indices);
|
||||
Self {
|
||||
buffer: buffers,
|
||||
usable_indices,
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
name = "web"
|
||||
version = "0.1.0"
|
||||
publish = false
|
||||
build = "build.rs"
|
||||
|
||||
description.workspace = true
|
||||
edition.workspace = true
|
||||
@ -44,6 +45,10 @@ console_log = { version = "0.2.0", features = ["color"] }
|
||||
tracing-wasm = { version = "0.2.1", optional = true } # TODO: Low quality dependency
|
||||
# For passing Inputs in AsyncProcedureCalls
|
||||
serde_json = "1.0.85"
|
||||
flatbuffers = "22.10.26"
|
||||
|
||||
[build-dependencies]
|
||||
flatc-rust = "0.2.0"
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "0.3.31"
|
||||
|
||||
26
web/build.rs
Normal file
26
web/build.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use std::{env, fs, path::Path};
|
||||
|
||||
fn main() {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
|
||||
println!("cargo:rerun-if-changed=./flatbuffer");
|
||||
|
||||
let flatbuffer = fs::read_dir("./flatbuffer")
|
||||
.unwrap()
|
||||
.map(|entry| entry.unwrap().path())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
flatc_rust::run(flatc_rust::Args {
|
||||
inputs: &flatbuffer
|
||||
.iter()
|
||||
.map(|buf| buf.as_path())
|
||||
.collect::<Vec<_>>(),
|
||||
out_dir: Path::new(&out_dir),
|
||||
extra: &[
|
||||
"--include-prefix",
|
||||
"platform::singlethreaded::transferables",
|
||||
],
|
||||
..Default::default()
|
||||
})
|
||||
.expect("flatc");
|
||||
}
|
||||
1
web/demo/package-lock.json
generated
1
web/demo/package-lock.json
generated
@ -26,6 +26,7 @@
|
||||
}
|
||||
},
|
||||
"../lib": {
|
||||
"name": "maplibre-rs",
|
||||
"version": "0.0.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
8
web/flatbuffer/basic.fbs
Normal file
8
web/flatbuffer/basic.fbs
Normal file
@ -0,0 +1,8 @@
|
||||
//namespace transferables;
|
||||
|
||||
|
||||
struct FlatWorldTileCoords {
|
||||
x: int;
|
||||
y: int;
|
||||
z: ubyte;
|
||||
}
|
||||
10
web/flatbuffer/layer_indexed.fbs
Normal file
10
web/flatbuffer/layer_indexed.fbs
Normal file
@ -0,0 +1,10 @@
|
||||
include "basic.fbs";
|
||||
|
||||
//namespace transferables;
|
||||
|
||||
table FlatLayerIndexed {
|
||||
coords: FlatWorldTileCoords;
|
||||
}
|
||||
|
||||
root_type FlatLayerIndexed;
|
||||
|
||||
18
web/flatbuffer/layer_tessellated.fbs
Normal file
18
web/flatbuffer/layer_tessellated.fbs
Normal file
@ -0,0 +1,18 @@
|
||||
include "basic.fbs";
|
||||
|
||||
struct FlatShaderVertex {
|
||||
position: [float:2];
|
||||
normal: [float:2];
|
||||
}
|
||||
|
||||
table FlatLayerTessellated {
|
||||
coords: FlatWorldTileCoords;
|
||||
layer_name: string;
|
||||
vertices: [FlatShaderVertex];
|
||||
indices: [uint];
|
||||
usable_indices: uint;
|
||||
// Holds for each feature the count of indices.
|
||||
feature_indices: [uint];
|
||||
}
|
||||
|
||||
root_type FlatLayerTessellated;
|
||||
10
web/flatbuffer/layer_unavailable.fbs
Normal file
10
web/flatbuffer/layer_unavailable.fbs
Normal file
@ -0,0 +1,10 @@
|
||||
include "basic.fbs";
|
||||
|
||||
//namespace transferables;
|
||||
|
||||
table FlatLayerUnavailable {
|
||||
coords: FlatWorldTileCoords;
|
||||
layer_name: string;
|
||||
}
|
||||
|
||||
root_type FlatLayerUnavailable;
|
||||
9
web/flatbuffer/tile_tessellated.fbs
Normal file
9
web/flatbuffer/tile_tessellated.fbs
Normal file
@ -0,0 +1,9 @@
|
||||
include "basic.fbs";
|
||||
|
||||
//namespace transferables;
|
||||
|
||||
table FlatTileTessellated {
|
||||
coords: FlatWorldTileCoords;
|
||||
}
|
||||
|
||||
root_type FlatTileTessellated;
|
||||
@ -72,7 +72,7 @@ let baseConfig = {
|
||||
|
||||
let config = {
|
||||
...baseConfig,
|
||||
entryPoints:['src/index.ts'],
|
||||
entryPoints: ['src/index.ts'],
|
||||
incremental: argv.watch,
|
||||
plugins: [
|
||||
inlineWorker({
|
||||
@ -108,23 +108,28 @@ const getLibDirectory = () => {
|
||||
const emitTypeScript = () => {
|
||||
let outDirectory = `${getLibDirectory()}/dist/ts`;
|
||||
|
||||
let child = spawnSync('npm', ["exec",
|
||||
let child = spawnTool('npm', ["exec",
|
||||
"tsc",
|
||||
"--",
|
||||
"-m", "es2022",
|
||||
"-outDir", outDirectory,
|
||||
"--declaration",
|
||||
"--emitDeclarationOnly"
|
||||
], {
|
||||
cwd: '.',
|
||||
stdio: 'inherit',
|
||||
});
|
||||
]);
|
||||
|
||||
if (child.status !== 0) {
|
||||
throw new Error("Failed to execute tsc")
|
||||
}
|
||||
}
|
||||
|
||||
const spawnTool = (program, args) => {
|
||||
console.debug(`Executing: ${program} ${args.join(" ")}`)
|
||||
return spawnSync(program, args, {
|
||||
cwd: '.',
|
||||
stdio: 'inherit',
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: Do not continue if one step fails
|
||||
const wasmPack = () => {
|
||||
let outDirectory = `${getLibDirectory()}/src/wasm`;
|
||||
@ -140,7 +145,7 @@ const wasmPack = () => {
|
||||
"-C", "link-args=--shared-memory --import-memory --max-memory=209715200"
|
||||
]`
|
||||
|
||||
let cargo = spawnSync('cargo', [
|
||||
let cargo = spawnTool('cargo', [
|
||||
...(multithreaded ? ["--config", multithreaded_config] : []),
|
||||
"build",
|
||||
"-p", "web", "--lib",
|
||||
@ -148,26 +153,20 @@ const wasmPack = () => {
|
||||
"--profile", profile,
|
||||
"--features", `${webgl ? "web-webgl," : ""}`,
|
||||
...(multithreaded ? ["-Z", "build-std=std,panic_abort"] : []),
|
||||
], {
|
||||
cwd: '.',
|
||||
stdio: 'inherit',
|
||||
});
|
||||
]);
|
||||
|
||||
if (cargo.status !== 0) {
|
||||
throw new Error("Failed to execute cargo build")
|
||||
}
|
||||
|
||||
let wasmbindgen = spawnSync('wasm-bindgen', [
|
||||
let wasmbindgen = spawnTool('wasm-bindgen', [
|
||||
`${getProjectDirectory()}/target/wasm32-unknown-unknown/${profile}/web.wasm`,
|
||||
"--out-name", "maplibre",
|
||||
"--out-dir", outDirectory,
|
||||
"--typescript",
|
||||
"--target", "web",
|
||||
"--debug",
|
||||
], {
|
||||
cwd: '.',
|
||||
stdio: 'inherit',
|
||||
});
|
||||
]);
|
||||
|
||||
if (wasmbindgen.status !== 0) {
|
||||
throw new Error("Failed to execute wasm-bindgen")
|
||||
@ -175,15 +174,12 @@ const wasmPack = () => {
|
||||
|
||||
if (release) {
|
||||
console.log("Running wasm-opt")
|
||||
let wasmOpt = spawnSync('npm', ["exec",
|
||||
let wasmOpt = spawnTool('npm', ["exec",
|
||||
"wasm-opt", "--",
|
||||
`${outDirectory}/maplibre_bg.wasm`,
|
||||
"-o", `${outDirectory}/maplibre_bg.wasm`,
|
||||
"-O"
|
||||
], {
|
||||
cwd: '.',
|
||||
stdio: 'inherit',
|
||||
});
|
||||
]);
|
||||
|
||||
if (wasmOpt.status !== 0) {
|
||||
throw new Error("Failed to execute wasm-opt")
|
||||
@ -238,26 +234,26 @@ const esbuild = async (name, globalName = undefined) => {
|
||||
|
||||
const start = async () => {
|
||||
try {
|
||||
console.log("Creating WASM...")
|
||||
wasmPack();
|
||||
console.log("Creating WASM...")
|
||||
wasmPack();
|
||||
|
||||
if (esm) {
|
||||
console.log("Building esm bundle...")
|
||||
await esbuild("esm")
|
||||
}
|
||||
if (esm) {
|
||||
console.log("Building esm bundle...")
|
||||
await esbuild("esm")
|
||||
}
|
||||
|
||||
if (cjs) {
|
||||
console.log("Building cjs bundle...")
|
||||
await esbuild("cjs")
|
||||
}
|
||||
if (cjs) {
|
||||
console.log("Building cjs bundle...")
|
||||
await esbuild("cjs")
|
||||
}
|
||||
|
||||
if (iife) {
|
||||
console.log("Building iife bundle...")
|
||||
await esbuild("iife", "maplibre")
|
||||
}
|
||||
if (iife) {
|
||||
console.log("Building iife bundle...")
|
||||
await esbuild("iife", "maplibre")
|
||||
}
|
||||
|
||||
console.log("Emitting TypeScript types...")
|
||||
emitTypeScript();
|
||||
console.log("Emitting TypeScript types...")
|
||||
emitTypeScript();
|
||||
} catch (e) {
|
||||
console.error("Failed to start building: " + e.message)
|
||||
process.exit(1)
|
||||
|
||||
@ -46,11 +46,10 @@ export const startMapLibre = async (wasmPath: string | undefined, workerPath: st
|
||||
}) : PoolWorker();
|
||||
|
||||
worker.onmessage = (message: MessageEvent) => {
|
||||
let tag = message.data[0];
|
||||
let data = new Uint8Array(message.data[1]);
|
||||
|
||||
// WARNING: Do not modify in_transfer_obj!
|
||||
let in_transfer_obj = message.data;
|
||||
// @ts-ignore TODO singlethreaded_main_entry may not be defined
|
||||
maplibre.singlethreaded_main_entry(ptr, tag, data)
|
||||
maplibre.singlethreaded_main_entry(ptr, in_transfer_obj)
|
||||
}
|
||||
|
||||
return worker;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#![deny(unused_imports)]
|
||||
#![feature(allocator_api, new_uninit)]
|
||||
#![feature(new_uninit)]
|
||||
|
||||
use maplibre::{
|
||||
event_loop::EventLoop,
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
pub mod pool;
|
||||
pub mod pool_scheduler;
|
||||
pub mod wasm_entries;
|
||||
|
||||
@ -7,7 +7,6 @@ use std::{cell::RefCell, rc::Rc};
|
||||
use js_sys::Promise;
|
||||
use rand::prelude::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::Worker;
|
||||
|
||||
#[wasm_bindgen()]
|
||||
@ -25,10 +24,26 @@ struct PoolState {
|
||||
workers: RefCell<Vec<Worker>>,
|
||||
}
|
||||
|
||||
struct Work {
|
||||
impl PoolState {
|
||||
fn push(&self, worker: Worker) {
|
||||
let mut workers = self.workers.borrow_mut();
|
||||
for existing_worker in workers.iter() {
|
||||
assert_ne!(existing_worker as &JsValue, &worker as &JsValue);
|
||||
}
|
||||
workers.push(worker);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Work {
|
||||
func: Box<dyn (FnOnce() -> Promise) + Send>,
|
||||
}
|
||||
|
||||
impl Work {
|
||||
pub fn execute(self) -> Promise {
|
||||
(self.func)()
|
||||
}
|
||||
}
|
||||
|
||||
impl WorkerPool {
|
||||
/// Creates a new `WorkerPool` which immediately creates `initial` workers.
|
||||
///
|
||||
@ -130,21 +145,3 @@ impl WorkerPool {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PoolState {
|
||||
fn push(&self, worker: Worker) {
|
||||
let mut workers = self.workers.borrow_mut();
|
||||
for existing_worker in workers.iter() {
|
||||
assert_ne!(existing_worker as &JsValue, &worker as &JsValue);
|
||||
}
|
||||
workers.push(worker);
|
||||
}
|
||||
}
|
||||
|
||||
/// Entry point invoked by the worker.
|
||||
#[wasm_bindgen]
|
||||
pub async fn multithreaded_worker_entry(ptr: u32) -> Result<(), JsValue> {
|
||||
let ptr = unsafe { Box::from_raw(ptr as *mut Work) };
|
||||
JsFuture::from((ptr.func)()).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
12
web/src/platform/multithreaded/wasm_entries.rs
Normal file
12
web/src/platform/multithreaded/wasm_entries.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
|
||||
use crate::platform::multithreaded::pool::Work;
|
||||
|
||||
/// Entry point invoked by the worker.
|
||||
#[wasm_bindgen]
|
||||
pub async fn multithreaded_worker_entry(ptr: u32) -> Result<(), JsValue> {
|
||||
let work = unsafe { Box::from_raw(ptr as *mut Work) };
|
||||
JsFuture::from(work.execute()).await?;
|
||||
Ok(())
|
||||
}
|
||||
@ -1,32 +1,23 @@
|
||||
use std::{cell::RefCell, mem, mem::size_of, rc::Rc, slice};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use js_sys::Uint8Array;
|
||||
use log::info;
|
||||
use js_sys::{ArrayBuffer, Uint8Array};
|
||||
use log::error;
|
||||
use maplibre::{
|
||||
error::Error,
|
||||
io::{
|
||||
apc::{AsyncProcedure, AsyncProcedureCall, Context, Input, Message},
|
||||
source_client::{HttpSourceClient, SourceClient},
|
||||
transferables::Transferables,
|
||||
source_client::SourceClient,
|
||||
},
|
||||
};
|
||||
use wasm_bindgen::{prelude::*, JsCast, JsValue};
|
||||
use wasm_bindgen::{JsCast, JsValue};
|
||||
use web_sys::{DedicatedWorkerGlobalScope, Worker};
|
||||
|
||||
use crate::{
|
||||
platform::singlethreaded::transferables::{
|
||||
InnerData, LinearLayerIndexed, LinearLayerTesselated, LinearLayerUnavailable,
|
||||
LinearTileTessellated, LinearTransferables,
|
||||
},
|
||||
WHATWGFetchHttpClient,
|
||||
use crate::platform::singlethreaded::{
|
||||
transferables::FlatBufferTransferable, UsedContext, UsedHttpClient, UsedTransferables,
|
||||
};
|
||||
|
||||
type UsedTransferables = LinearTransferables;
|
||||
type UsedHttpClient = WHATWGFetchHttpClient;
|
||||
type UsedContext = PassingContext;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum SerializedMessageTag {
|
||||
pub enum SerializedMessageTag {
|
||||
TileTessellated = 1,
|
||||
LayerUnavailable = 2,
|
||||
LayerTessellated = 3,
|
||||
@ -34,7 +25,16 @@ enum SerializedMessageTag {
|
||||
}
|
||||
|
||||
impl SerializedMessageTag {
|
||||
fn from_u32(tag: u32) -> Option<Self> {
|
||||
pub fn from_message(message: &Message<UsedTransferables>) -> Self {
|
||||
match message {
|
||||
Message::TileTessellated(_) => SerializedMessageTag::TileTessellated,
|
||||
Message::LayerUnavailable(_) => SerializedMessageTag::LayerUnavailable,
|
||||
Message::LayerTessellated(_) => SerializedMessageTag::LayerTessellated,
|
||||
Message::LayerIndexed(_) => SerializedMessageTag::LayerIndexed,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_u32(tag: u32) -> Option<Self> {
|
||||
match tag {
|
||||
x if x == SerializedMessageTag::LayerUnavailable as u32 => {
|
||||
Some(SerializedMessageTag::LayerUnavailable)
|
||||
@ -53,107 +53,43 @@ impl SerializedMessageTag {
|
||||
}
|
||||
}
|
||||
|
||||
trait SerializableMessage {
|
||||
fn serialize(&self) -> &[u8];
|
||||
|
||||
fn deserialize(tag: SerializedMessageTag, data: Uint8Array) -> Message<UsedTransferables>;
|
||||
|
||||
fn tag(&self) -> SerializedMessageTag;
|
||||
}
|
||||
|
||||
impl SerializableMessage for Message<LinearTransferables> {
|
||||
fn serialize(&self) -> &[u8] {
|
||||
unsafe {
|
||||
match self {
|
||||
// TODO https://github.com/Lokathor/bytemuck/blob/518baf9c0b73c92b4ea4406fe15e005c6d71535a/src/internal.rs#L333
|
||||
Message::TileTessellated(message) => slice::from_raw_parts(
|
||||
message as *const LinearTileTessellated as *mut u8,
|
||||
size_of::<LinearTileTessellated>(),
|
||||
),
|
||||
Message::LayerUnavailable(message) => slice::from_raw_parts(
|
||||
message as *const LinearLayerUnavailable as *mut u8,
|
||||
size_of::<LinearLayerUnavailable>(),
|
||||
),
|
||||
Message::LayerTessellated(message) => slice::from_raw_parts(
|
||||
message.data.as_ref() as *const InnerData as *mut u8,
|
||||
size_of::<InnerData>(),
|
||||
),
|
||||
Message::LayerIndexed(message) => slice::from_raw_parts(
|
||||
message as *const LinearLayerIndexed as *mut u8,
|
||||
size_of::<LinearLayerIndexed>(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize(tag: SerializedMessageTag, data: Uint8Array) -> Message<UsedTransferables> {
|
||||
type TileTessellated = <UsedTransferables as Transferables>::TileTessellated;
|
||||
type UnavailableLayer = <UsedTransferables as Transferables>::LayerUnavailable;
|
||||
type IndexedLayer = <UsedTransferables as Transferables>::LayerIndexed;
|
||||
unsafe {
|
||||
// TODO: https://github.com/Lokathor/bytemuck/blob/518baf9c0b73c92b4ea4406fe15e005c6d71535a/src/internal.rs#L159
|
||||
match tag {
|
||||
SerializedMessageTag::TileTessellated => {
|
||||
Message::<UsedTransferables>::TileTessellated(
|
||||
(&*(data.to_vec().as_slice() as *const [u8] as *const TileTessellated))
|
||||
.clone(),
|
||||
)
|
||||
}
|
||||
SerializedMessageTag::LayerUnavailable => {
|
||||
Message::<UsedTransferables>::LayerUnavailable(
|
||||
(&*(data.to_vec().as_slice() as *const [u8] as *const UnavailableLayer))
|
||||
.clone(),
|
||||
)
|
||||
}
|
||||
SerializedMessageTag::LayerTessellated => {
|
||||
Message::<UsedTransferables>::LayerTessellated(LinearLayerTesselated {
|
||||
data: unsafe {
|
||||
let mut uninit = Box::<InnerData>::new_zeroed();
|
||||
data.raw_copy_to_ptr(uninit.as_mut_ptr() as *mut u8);
|
||||
|
||||
uninit.assume_init()
|
||||
},
|
||||
})
|
||||
}
|
||||
SerializedMessageTag::LayerIndexed => Message::<UsedTransferables>::LayerIndexed(
|
||||
(&*(data.to_vec().as_slice() as *const [u8] as *const IndexedLayer)).clone(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn tag(&self) -> SerializedMessageTag {
|
||||
match self {
|
||||
Message::TileTessellated(_) => SerializedMessageTag::TileTessellated,
|
||||
Message::LayerUnavailable(_) => SerializedMessageTag::LayerUnavailable,
|
||||
Message::LayerTessellated(_) => SerializedMessageTag::LayerTessellated,
|
||||
Message::LayerIndexed(_) => SerializedMessageTag::LayerIndexed,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PassingContext {
|
||||
source_client: SourceClient<UsedHttpClient>,
|
||||
pub source_client: SourceClient<UsedHttpClient>,
|
||||
}
|
||||
|
||||
impl Context<UsedTransferables, UsedHttpClient> for PassingContext {
|
||||
fn send(&self, data: Message<UsedTransferables>) -> Result<(), Error> {
|
||||
let tag = data.tag();
|
||||
let serialized = data.serialize();
|
||||
fn send(&self, message: Message<UsedTransferables>) -> Result<(), Error> {
|
||||
let tag = SerializedMessageTag::from_message(&message);
|
||||
let transferable = FlatBufferTransferable::from_message(message);
|
||||
let data = &transferable.data[transferable.start..];
|
||||
|
||||
let serialized_array_buffer = js_sys::ArrayBuffer::new(serialized.len() as u32);
|
||||
let serialized_array = js_sys::Uint8Array::new(&serialized_array_buffer);
|
||||
let buffer = ArrayBuffer::new(data.len() as u32);
|
||||
let byte_buffer = Uint8Array::new(&buffer);
|
||||
unsafe {
|
||||
serialized_array.set(&Uint8Array::view(serialized), 0);
|
||||
byte_buffer.set(&Uint8Array::view(data), 0);
|
||||
}
|
||||
|
||||
let tag = tag as u32;
|
||||
|
||||
let global: DedicatedWorkerGlobalScope =
|
||||
js_sys::global().dyn_into().map_err(|_e| Error::APC)?;
|
||||
let array = js_sys::Array::new();
|
||||
array.push(&JsValue::from(tag as u32));
|
||||
array.push(&serialized_array_buffer);
|
||||
global.post_message(&array).map_err(|_e| Error::APC)
|
||||
|
||||
let transfer_obj = js_sys::Array::new();
|
||||
transfer_obj.push(&JsValue::from(tag));
|
||||
|
||||
transfer_obj.push(&buffer);
|
||||
|
||||
let transfer = js_sys::Array::new();
|
||||
transfer.push(&buffer);
|
||||
|
||||
// TODO: Verify transfer
|
||||
global
|
||||
.post_message_with_transfer(&transfer_obj, &transfer)
|
||||
.map_err(|e| {
|
||||
error!("{:?}", e);
|
||||
Error::APC
|
||||
})
|
||||
}
|
||||
|
||||
fn source_client(&self) -> &SourceClient<UsedHttpClient> {
|
||||
@ -161,7 +97,7 @@ impl Context<UsedTransferables, UsedHttpClient> for PassingContext {
|
||||
}
|
||||
}
|
||||
|
||||
type ReceivedType = RefCell<Vec<Message<UsedTransferables>>>;
|
||||
pub type ReceivedType = RefCell<Vec<Message<UsedTransferables>>>;
|
||||
|
||||
pub struct PassingAsyncProcedureCall {
|
||||
new_worker: Box<dyn Fn() -> Worker>,
|
||||
@ -210,7 +146,10 @@ impl AsyncProcedureCall<UsedHttpClient> for PassingAsyncProcedureCall {
|
||||
type Transferables = UsedTransferables;
|
||||
|
||||
fn receive(&self) -> Option<Message<UsedTransferables>> {
|
||||
self.received.borrow_mut().pop()
|
||||
self.received
|
||||
.try_borrow_mut()
|
||||
.expect("Failed to borrow in receive of APC")
|
||||
.pop()
|
||||
}
|
||||
|
||||
fn call(&self, input: Input, procedure: AsyncProcedure<Self::Context>) {
|
||||
@ -224,44 +163,3 @@ impl AsyncProcedureCall<UsedHttpClient> for PassingAsyncProcedureCall {
|
||||
self.workers[0].post_message(&array).unwrap(); // FIXME (wasm-executor): Remove unwrap
|
||||
}
|
||||
}
|
||||
|
||||
/// Entry point invoked by the worker.
|
||||
#[wasm_bindgen]
|
||||
pub async fn singlethreaded_worker_entry(procedure_ptr: u32, input: String) -> Result<(), JsValue> {
|
||||
let procedure: AsyncProcedure<UsedContext> = unsafe { std::mem::transmute(procedure_ptr) };
|
||||
|
||||
let input = serde_json::from_str::<Input>(&input).unwrap(); // FIXME (wasm-executor): Remove unwrap
|
||||
|
||||
let context = PassingContext {
|
||||
source_client: SourceClient::new(HttpSourceClient::new(WHATWGFetchHttpClient::new())),
|
||||
};
|
||||
|
||||
(procedure)(input, context).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Entry point invoked by the main thread.
|
||||
#[wasm_bindgen]
|
||||
pub unsafe fn singlethreaded_main_entry(
|
||||
received_ptr: *const ReceivedType,
|
||||
type_id: u32,
|
||||
data: Uint8Array,
|
||||
) -> Result<(), JsValue> {
|
||||
// FIXME (wasm-executor): Can we make this call safe? check if it was cloned before?
|
||||
let received: Rc<ReceivedType> = Rc::from_raw(received_ptr);
|
||||
|
||||
let message = Message::<UsedTransferables>::deserialize(
|
||||
SerializedMessageTag::from_u32(type_id).unwrap(),
|
||||
data,
|
||||
);
|
||||
|
||||
info!("singlethreaded_main_entry {:?}", message.tag());
|
||||
|
||||
// MAJOR FIXME: Fix mutability
|
||||
received.borrow_mut().push(message);
|
||||
|
||||
mem::forget(received); // FIXME (wasm-executor): Enforce this somehow
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -1,2 +1,12 @@
|
||||
use crate::platform::{
|
||||
http_client::WHATWGFetchHttpClient,
|
||||
singlethreaded::{apc::PassingContext, transferables::FlatTransferables},
|
||||
};
|
||||
|
||||
pub mod apc;
|
||||
pub mod transferables;
|
||||
pub mod wasm_entries;
|
||||
|
||||
pub type UsedTransferables = FlatTransferables;
|
||||
pub type UsedHttpClient = WHATWGFetchHttpClient;
|
||||
pub type UsedContext = PassingContext;
|
||||
|
||||
@ -1,236 +1,235 @@
|
||||
use log::warn;
|
||||
use flatbuffers::FlatBufferBuilder;
|
||||
use maplibre::{
|
||||
benchmarking::tessellation::{IndexDataType, OverAlignedVertexBuffer},
|
||||
coords::WorldTileCoords,
|
||||
io::{
|
||||
apc::Message,
|
||||
geometry_index::TileIndex,
|
||||
tile_repository::StoredLayer,
|
||||
transferables::{
|
||||
IndexedLayer, TessellatedLayer, TileTessellated, Transferables, UnavailableLayer,
|
||||
LayerIndexed, LayerTessellated, LayerUnavailable, TileTessellated, Transferables,
|
||||
},
|
||||
},
|
||||
render::ShaderVertex,
|
||||
tile::Layer,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct LinearTileTessellated {
|
||||
pub coords: WorldTileCoords,
|
||||
pub _padding: u8,
|
||||
}
|
||||
use crate::platform::singlethreaded::{
|
||||
transferables::{
|
||||
basic_generated::*, layer_indexed_generated::*, layer_tessellated_generated::*,
|
||||
layer_unavailable_generated::*, tile_tessellated_generated::*,
|
||||
},
|
||||
UsedTransferables,
|
||||
};
|
||||
|
||||
impl TileTessellated for LinearTileTessellated {
|
||||
fn new(coords: WorldTileCoords) -> Self {
|
||||
Self {
|
||||
coords,
|
||||
_padding: 0,
|
||||
pub mod basic_generated {
|
||||
#![allow(unused, unused_imports, clippy::all)]
|
||||
|
||||
use maplibre::coords::{WorldTileCoords, ZoomLevel};
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/basic_generated.rs"));
|
||||
|
||||
impl Into<WorldTileCoords> for &FlatWorldTileCoords {
|
||||
fn into(self) -> WorldTileCoords {
|
||||
WorldTileCoords {
|
||||
x: self.x(),
|
||||
y: self.y(),
|
||||
z: ZoomLevel::new(self.z()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn coords(&self) -> &WorldTileCoords {
|
||||
&self.coords
|
||||
}
|
||||
}
|
||||
pub mod layer_indexed_generated {
|
||||
#![allow(unused, unused_imports, clippy::all)]
|
||||
include!(concat!(env!("OUT_DIR"), "/layer_indexed_generated.rs"));
|
||||
}
|
||||
pub mod layer_tessellated_generated {
|
||||
#![allow(unused, unused_imports, clippy::all)]
|
||||
include!(concat!(env!("OUT_DIR"), "/layer_tessellated_generated.rs"));
|
||||
}
|
||||
pub mod layer_unavailable_generated {
|
||||
#![allow(unused, unused_imports, clippy::all)]
|
||||
include!(concat!(env!("OUT_DIR"), "/layer_unavailable_generated.rs"));
|
||||
}
|
||||
pub mod tile_tessellated_generated {
|
||||
#![allow(unused, unused_imports, clippy::all)]
|
||||
include!(concat!(env!("OUT_DIR"), "/tile_tessellated_generated.rs"));
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct LinearLayerUnavailable {
|
||||
pub coords: WorldTileCoords,
|
||||
pub layer_name: [u8; 32],
|
||||
pub struct FlatBufferTransferable {
|
||||
pub data: Vec<u8>,
|
||||
pub start: usize,
|
||||
}
|
||||
|
||||
impl UnavailableLayer for LinearLayerUnavailable {
|
||||
fn new(coords: WorldTileCoords, layer_name: String) -> Self {
|
||||
let mut new_layer_name = [0; 32];
|
||||
new_layer_name[0..layer_name.len()].clone_from_slice(layer_name.as_bytes());
|
||||
Self {
|
||||
coords,
|
||||
layer_name: new_layer_name,
|
||||
impl FlatBufferTransferable {
|
||||
pub fn from_message(message: Message<UsedTransferables>) -> Self {
|
||||
match message {
|
||||
Message::TileTessellated(transferable) => transferable,
|
||||
Message::LayerUnavailable(transferable) => transferable,
|
||||
Message::LayerTessellated(transferable) => transferable,
|
||||
Message::LayerIndexed(transferable) => transferable,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn coords(&self) -> &WorldTileCoords {
|
||||
&self.coords
|
||||
impl TileTessellated for FlatBufferTransferable {
|
||||
fn build_from(coords: WorldTileCoords) -> Self {
|
||||
let mut inner_builder = FlatBufferBuilder::with_capacity(1024);
|
||||
let mut builder = FlatTileTessellatedBuilder::new(&mut inner_builder);
|
||||
|
||||
builder.add_coords(&FlatWorldTileCoords::new(
|
||||
coords.x,
|
||||
coords.y,
|
||||
coords.z.into(),
|
||||
));
|
||||
let root = builder.finish();
|
||||
inner_builder.finish(root, None);
|
||||
let (data, start) = inner_builder.collapse();
|
||||
FlatBufferTransferable { data, start }
|
||||
}
|
||||
|
||||
fn coords(&self) -> WorldTileCoords {
|
||||
let data = unsafe { root_as_flat_tile_tessellated_unchecked(&self.data[self.start..]) };
|
||||
data.coords().unwrap().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl LayerUnavailable for FlatBufferTransferable {
|
||||
fn build_from(coords: WorldTileCoords, layer_name: String) -> Self {
|
||||
let mut inner_builder = FlatBufferBuilder::with_capacity(1024);
|
||||
let layer_name = inner_builder.create_string(&layer_name);
|
||||
|
||||
let mut builder = FlatLayerUnavailableBuilder::new(&mut inner_builder);
|
||||
builder.add_coords(&FlatWorldTileCoords::new(
|
||||
coords.x,
|
||||
coords.y,
|
||||
coords.z.into(),
|
||||
));
|
||||
builder.add_layer_name(layer_name);
|
||||
let root = builder.finish();
|
||||
|
||||
inner_builder.finish(root, None);
|
||||
let (data, start) = inner_builder.collapse();
|
||||
FlatBufferTransferable { data, start }
|
||||
}
|
||||
|
||||
fn coords(&self) -> WorldTileCoords {
|
||||
let data = unsafe { root_as_flat_layer_unavailable_unchecked(&self.data[self.start..]) };
|
||||
data.coords().unwrap().into()
|
||||
}
|
||||
|
||||
fn layer_name(&self) -> &str {
|
||||
let data = unsafe { root_as_flat_layer_unavailable_unchecked(&self.data[self.start..]) };
|
||||
data.layer_name().expect("property must be set")
|
||||
}
|
||||
|
||||
fn to_stored_layer(self) -> StoredLayer {
|
||||
StoredLayer::UnavailableLayer {
|
||||
coords: self.coords,
|
||||
layer_name: String::from_utf8(Vec::from(self.layer_name)).unwrap(), // FIXME (wasm-executor): Remove unwrap
|
||||
layer_name: self.layer_name().to_owned(),
|
||||
coords: LayerUnavailable::coords(&self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct InnerData {
|
||||
pub coords: WorldTileCoords,
|
||||
pub layer_name: [u8; 32],
|
||||
pub layer_name_len: usize,
|
||||
pub vertices: [ShaderVertex; 15000],
|
||||
pub vertices_len: usize,
|
||||
pub indices: [IndexDataType; 40000],
|
||||
pub indices_len: usize,
|
||||
pub usable_indices: u32,
|
||||
/// Holds for each feature the count of indices.
|
||||
pub feature_indices: [u32; 2048],
|
||||
pub feature_indices_len: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LinearLayerTesselated {
|
||||
pub data: Box<InnerData>,
|
||||
}
|
||||
|
||||
impl TessellatedLayer for LinearLayerTesselated {
|
||||
fn new(
|
||||
impl LayerTessellated for FlatBufferTransferable {
|
||||
fn build_from(
|
||||
coords: WorldTileCoords,
|
||||
buffer: OverAlignedVertexBuffer<ShaderVertex, IndexDataType>,
|
||||
feature_indices: Vec<u32>,
|
||||
layer_data: Layer,
|
||||
) -> Self {
|
||||
let mut data = Box::new(InnerData {
|
||||
coords,
|
||||
let mut inner_builder = FlatBufferBuilder::with_capacity(1024);
|
||||
|
||||
layer_name: [0; 32],
|
||||
layer_name_len: layer_data.name.len(),
|
||||
let vertices = inner_builder.create_vector(
|
||||
&buffer
|
||||
.buffer
|
||||
.vertices
|
||||
.iter()
|
||||
.map(|vertex| FlatShaderVertex::new(&vertex.position, &vertex.normal))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
let indices = inner_builder.create_vector(&buffer.buffer.indices);
|
||||
let feature_indices = inner_builder.create_vector(&feature_indices);
|
||||
let layer_name = inner_builder.create_string(&layer_data.name);
|
||||
|
||||
vertices: [ShaderVertex::new([0.0, 0.0], [0.0, 0.0]); 15000],
|
||||
vertices_len: buffer.buffer.vertices.len(),
|
||||
let mut builder = FlatLayerTessellatedBuilder::new(&mut inner_builder);
|
||||
|
||||
indices: [0; 40000],
|
||||
indices_len: buffer.buffer.indices.len(),
|
||||
builder.add_coords(&FlatWorldTileCoords::new(
|
||||
coords.x,
|
||||
coords.y,
|
||||
coords.z.into(),
|
||||
));
|
||||
builder.add_layer_name(layer_name);
|
||||
builder.add_vertices(vertices);
|
||||
builder.add_indices(indices);
|
||||
builder.add_feature_indices(feature_indices);
|
||||
builder.add_usable_indices(buffer.usable_indices);
|
||||
let root = builder.finish();
|
||||
|
||||
usable_indices: buffer.usable_indices,
|
||||
|
||||
feature_indices: [0u32; 2048],
|
||||
feature_indices_len: feature_indices.len(),
|
||||
});
|
||||
|
||||
if buffer.buffer.vertices.len() > 15000 {
|
||||
warn!("vertices too large");
|
||||
return Self {
|
||||
data: Box::new(InnerData {
|
||||
coords,
|
||||
|
||||
layer_name: [0; 32],
|
||||
layer_name_len: 0,
|
||||
|
||||
vertices: [ShaderVertex::new([0.0, 0.0], [0.0, 0.0]); 15000],
|
||||
vertices_len: 0,
|
||||
|
||||
indices: [0; 40000],
|
||||
indices_len: 0,
|
||||
|
||||
usable_indices: 0,
|
||||
|
||||
feature_indices: [0u32; 2048],
|
||||
feature_indices_len: 0,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
if buffer.buffer.indices.len() > 40000 {
|
||||
warn!("indices too large");
|
||||
return Self {
|
||||
data: Box::new(InnerData {
|
||||
coords,
|
||||
|
||||
layer_name: [0; 32],
|
||||
layer_name_len: 0,
|
||||
|
||||
vertices: [ShaderVertex::new([0.0, 0.0], [0.0, 0.0]); 15000],
|
||||
vertices_len: 0,
|
||||
|
||||
indices: [0; 40000],
|
||||
indices_len: 0,
|
||||
|
||||
usable_indices: 0,
|
||||
|
||||
feature_indices: [0u32; 2048],
|
||||
feature_indices_len: 0,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
if feature_indices.len() > 2048 {
|
||||
warn!("feature_indices too large");
|
||||
return Self {
|
||||
data: Box::new(InnerData {
|
||||
coords,
|
||||
|
||||
layer_name: [0; 32],
|
||||
layer_name_len: 0,
|
||||
|
||||
vertices: [ShaderVertex::new([0.0, 0.0], [0.0, 0.0]); 15000],
|
||||
vertices_len: 0,
|
||||
|
||||
indices: [0; 40000],
|
||||
indices_len: 0,
|
||||
|
||||
usable_indices: 0,
|
||||
|
||||
feature_indices: [0u32; 2048],
|
||||
feature_indices_len: 0,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
data.vertices[0..buffer.buffer.vertices.len()].clone_from_slice(&buffer.buffer.vertices);
|
||||
data.indices[0..buffer.buffer.indices.len()].clone_from_slice(&buffer.buffer.indices);
|
||||
data.feature_indices[0..feature_indices.len()].clone_from_slice(&feature_indices);
|
||||
data.layer_name[0..layer_data.name.len()].clone_from_slice(layer_data.name.as_bytes());
|
||||
|
||||
Self { data }
|
||||
inner_builder.finish(root, None);
|
||||
let (data, start) = inner_builder.collapse();
|
||||
FlatBufferTransferable { data, start }
|
||||
}
|
||||
|
||||
fn coords(&self) -> &WorldTileCoords {
|
||||
&self.data.coords
|
||||
fn coords(&self) -> WorldTileCoords {
|
||||
let data = unsafe { root_as_flat_layer_tessellated_unchecked(&self.data[self.start..]) };
|
||||
data.coords().unwrap().into()
|
||||
}
|
||||
|
||||
fn to_stored_layer(self) -> StoredLayer {
|
||||
// TODO: Avoid copies here
|
||||
let data = unsafe { root_as_flat_layer_tessellated_unchecked(&self.data[self.start..]) };
|
||||
let vertices = data
|
||||
.vertices()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|vertex| ShaderVertex::new(vertex.position().into(), vertex.normal().into()));
|
||||
|
||||
let indices = data.indices().unwrap();
|
||||
let feature_indices: Vec<u32> = data.feature_indices().unwrap().iter().collect();
|
||||
let usable_indices = data.usable_indices();
|
||||
StoredLayer::TessellatedLayer {
|
||||
coords: self.data.coords,
|
||||
layer_name: String::from_utf8(Vec::from(
|
||||
&self.data.layer_name[..self.data.layer_name_len],
|
||||
))
|
||||
.unwrap(), // FIXME (wasm-executor): Remove unwrap
|
||||
buffer: OverAlignedVertexBuffer::from_slices(
|
||||
&self.data.vertices[..self.data.vertices_len],
|
||||
&self.data.indices[..self.data.indices_len],
|
||||
self.data.usable_indices,
|
||||
),
|
||||
feature_indices: Vec::from(&self.data.feature_indices[..self.data.feature_indices_len]),
|
||||
coords: LayerTessellated::coords(&self),
|
||||
layer_name: data.layer_name().unwrap().to_owned(),
|
||||
buffer: OverAlignedVertexBuffer::from_iters(vertices, indices, usable_indices),
|
||||
feature_indices,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LayerIndexed for FlatBufferTransferable {
|
||||
fn build_from(coords: WorldTileCoords, _index: TileIndex) -> Self {
|
||||
let mut inner_builder = FlatBufferBuilder::with_capacity(1024);
|
||||
let mut builder = FlatLayerIndexedBuilder::new(&mut inner_builder);
|
||||
|
||||
// TODO index
|
||||
|
||||
builder.add_coords(&FlatWorldTileCoords::new(
|
||||
coords.x,
|
||||
coords.y,
|
||||
coords.z.into(),
|
||||
));
|
||||
let root = builder.finish();
|
||||
inner_builder.finish(root, None);
|
||||
let (data, start) = inner_builder.collapse();
|
||||
FlatBufferTransferable { data, start }
|
||||
}
|
||||
|
||||
fn coords(&self) -> WorldTileCoords {
|
||||
let data = unsafe { root_as_flat_layer_indexed_unchecked(&self.data[self.start..]) };
|
||||
data.coords().unwrap().into()
|
||||
}
|
||||
|
||||
fn to_tile_index(self) -> TileIndex {
|
||||
TileIndex::Linear { list: vec![] } // TODO
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct LinearLayerIndexed {
|
||||
pub coords: WorldTileCoords,
|
||||
}
|
||||
|
||||
impl From<(WorldTileCoords, TileIndex)> for LinearLayerIndexed {
|
||||
fn from((coords, _index): (WorldTileCoords, TileIndex)) -> Self {
|
||||
Self { coords }
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexedLayer for LinearLayerIndexed {
|
||||
fn coords(&self) -> &WorldTileCoords {
|
||||
&self.coords
|
||||
}
|
||||
|
||||
fn to_tile_index(self) -> TileIndex {
|
||||
// FIXME replace this stub implementation
|
||||
TileIndex::Linear { list: vec![] }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LinearTransferables;
|
||||
|
||||
impl Transferables for LinearTransferables {
|
||||
type TileTessellated = LinearTileTessellated;
|
||||
type LayerUnavailable = LinearLayerUnavailable;
|
||||
type LayerTessellated = LinearLayerTesselated;
|
||||
type LayerIndexed = LinearLayerIndexed;
|
||||
pub struct FlatTransferables;
|
||||
|
||||
impl Transferables for FlatTransferables {
|
||||
type TileTessellated = FlatBufferTransferable;
|
||||
type LayerUnavailable = FlatBufferTransferable;
|
||||
type LayerTessellated = FlatBufferTransferable;
|
||||
type LayerIndexed = FlatBufferTransferable;
|
||||
}
|
||||
|
||||
95
web/src/platform/singlethreaded/wasm_entries.rs
Normal file
95
web/src/platform/singlethreaded/wasm_entries.rs
Normal file
@ -0,0 +1,95 @@
|
||||
use std::{mem, rc::Rc};
|
||||
|
||||
use js_sys::{ArrayBuffer, Uint8Array};
|
||||
use log::{error, info};
|
||||
use maplibre::{
|
||||
benchmarking::io::{
|
||||
apc::{AsyncProcedure, Input, Message},
|
||||
source_client::{HttpSourceClient, SourceClient},
|
||||
},
|
||||
io::transferables::Transferables,
|
||||
};
|
||||
use wasm_bindgen::{prelude::*, JsCast};
|
||||
|
||||
use crate::{
|
||||
platform::singlethreaded::{
|
||||
apc::{ReceivedType, SerializedMessageTag},
|
||||
transferables::FlatBufferTransferable,
|
||||
PassingContext, UsedContext, UsedTransferables,
|
||||
},
|
||||
WHATWGFetchHttpClient,
|
||||
};
|
||||
|
||||
/// Entry point invoked by the worker.
|
||||
#[wasm_bindgen]
|
||||
pub async fn singlethreaded_worker_entry(procedure_ptr: u32, input: String) -> Result<(), JsValue> {
|
||||
let procedure: AsyncProcedure<UsedContext> = unsafe { mem::transmute(procedure_ptr) };
|
||||
|
||||
let input = serde_json::from_str::<Input>(&input).unwrap(); // FIXME (wasm-executor): Remove unwrap
|
||||
|
||||
let context = PassingContext {
|
||||
source_client: SourceClient::new(HttpSourceClient::new(WHATWGFetchHttpClient::new())),
|
||||
};
|
||||
|
||||
let result = (procedure)(input, context).await;
|
||||
|
||||
if let Err(e) = result {
|
||||
error!("{:?}", e); // TODO handle better
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Entry point invoked by the main thread.
|
||||
#[wasm_bindgen]
|
||||
pub unsafe fn singlethreaded_main_entry(
|
||||
received_ptr: *const ReceivedType,
|
||||
in_transfer_obj: js_sys::Array,
|
||||
) -> Result<(), JsValue> {
|
||||
// FIXME (wasm-executor): Can we make this call safe? check if it was cloned before?
|
||||
let received: Rc<ReceivedType> = Rc::from_raw(received_ptr);
|
||||
|
||||
let tag = in_transfer_obj.get(0).as_f64().unwrap() as u32;
|
||||
let tag = SerializedMessageTag::from_u32(tag).unwrap();
|
||||
|
||||
info!("singlethreaded_main_entry {:?}", tag);
|
||||
|
||||
let buffer: ArrayBuffer = in_transfer_obj.get(1).dyn_into().unwrap();
|
||||
let buffer = Uint8Array::new(&buffer);
|
||||
|
||||
type TileTessellated = <UsedTransferables as Transferables>::TileTessellated;
|
||||
type UnavailableLayer = <UsedTransferables as Transferables>::LayerUnavailable;
|
||||
type IndexedLayer = <UsedTransferables as Transferables>::LayerIndexed;
|
||||
|
||||
let transferable = FlatBufferTransferable {
|
||||
data: buffer.to_vec(),
|
||||
start: 0,
|
||||
};
|
||||
|
||||
// TODO: Verify that data matches tag
|
||||
|
||||
let message = match tag {
|
||||
SerializedMessageTag::TileTessellated => {
|
||||
Message::<UsedTransferables>::TileTessellated(transferable)
|
||||
}
|
||||
SerializedMessageTag::LayerUnavailable => {
|
||||
Message::<UsedTransferables>::LayerUnavailable(transferable)
|
||||
}
|
||||
SerializedMessageTag::LayerTessellated => {
|
||||
Message::<UsedTransferables>::LayerTessellated(transferable)
|
||||
}
|
||||
SerializedMessageTag::LayerIndexed => {
|
||||
Message::<UsedTransferables>::LayerIndexed(transferable)
|
||||
}
|
||||
};
|
||||
|
||||
// MAJOR FIXME: Fix mutability
|
||||
received
|
||||
.try_borrow_mut()
|
||||
.expect("Failed to borrow in singlethreaded_main_entry")
|
||||
.push(message);
|
||||
|
||||
mem::forget(received); // FIXME (wasm-executor): Enforce this somehow
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user