mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
130 lines
3.5 KiB
TypeScript
130 lines
3.5 KiB
TypeScript
import init, {create_pool_scheduler, new_thread_local_state, run} from "./dist/libs/mapr"
|
|
import {Spector} from "spectorjs"
|
|
import {WebWorkerMessageType} from "./types"
|
|
|
|
declare global {
|
|
interface Window {
|
|
schedule_tile_request: (url: string, request_id: number) => void;
|
|
newWorker: () => void;
|
|
}
|
|
}
|
|
|
|
const isWebGLSupported = () => {
|
|
try {
|
|
const canvas = document.createElement('canvas')
|
|
canvas.getContext("webgl")
|
|
return true
|
|
} catch (x) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
const alertUser = (message: string) => {
|
|
console.error(message)
|
|
alert(message)
|
|
}
|
|
|
|
const checkRequirements = () => {
|
|
if (!isSecureContext) {
|
|
alertUser("isSecureContext is false!")
|
|
return false
|
|
}
|
|
|
|
if (!crossOriginIsolated) {
|
|
alertUser("crossOriginIsolated is false! " +
|
|
"The Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy HTTP headers are required.")
|
|
return false
|
|
}
|
|
|
|
if (WEBGL) {
|
|
if (!isWebGLSupported()) {
|
|
alertUser("WebGL is not supported in this Browser!")
|
|
return false
|
|
}
|
|
|
|
let spector = new Spector()
|
|
spector.displayUI()
|
|
} else {
|
|
if (!("gpu" in navigator)) {
|
|
let message = "WebGPU is not supported in this Browser!"
|
|
alertUser(message)
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
const preventDefaultTouchActions = () => {
|
|
document.body.querySelectorAll("canvas").forEach(canvas => {
|
|
canvas.addEventListener("touchstart", e => e.preventDefault())
|
|
canvas.addEventListener("touchmove", e => e.preventDefault())
|
|
})
|
|
}
|
|
|
|
const registerServiceWorker = () => {
|
|
if ('serviceWorker' in navigator) {
|
|
window.addEventListener('load', () => {
|
|
navigator.serviceWorker.register(new URL('./service-worker.ts', import.meta.url)).catch(() => {
|
|
console.error("Failed to register service worker");
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
const setupLegacyWebWorker = (schedulerPtr: number, memory: WebAssembly.Memory) => {
|
|
let WORKER_COUNT = 4
|
|
const createWorker = (id: number) => {
|
|
const worker = new Worker(new URL('./worker.ts', import.meta.url), {
|
|
type: "module",
|
|
name: `worker_${id}`
|
|
})
|
|
worker.postMessage({type: "init", memory} as WebWorkerMessageType)
|
|
|
|
return worker
|
|
}
|
|
|
|
let workers: [number, Worker][] = Array.from(
|
|
new Array(WORKER_COUNT).keys(),
|
|
(id) => [new_thread_local_state(schedulerPtr), createWorker(id)]
|
|
)
|
|
|
|
window.schedule_tile_request = (url: string, request_id: number) => {
|
|
const [state, worker] = workers[Math.floor(Math.random() * workers.length)]
|
|
worker.postMessage({
|
|
type: "fetch_tile",
|
|
threadLocalState: state,
|
|
url,
|
|
request_id
|
|
} as WebWorkerMessageType)
|
|
}
|
|
}
|
|
|
|
const start = async () => {
|
|
if (!checkRequirements()) {
|
|
return
|
|
}
|
|
|
|
registerServiceWorker()
|
|
|
|
preventDefaultTouchActions();
|
|
|
|
let MEMORY_PAGES = 16 * 1024
|
|
|
|
const memory = new WebAssembly.Memory({initial: 1024, maximum: MEMORY_PAGES, shared: true})
|
|
await init(undefined, memory)
|
|
const schedulerPtr = create_pool_scheduler(() => {
|
|
return new Worker(new URL('./pool_worker.ts', import.meta.url), {
|
|
type: 'module'
|
|
});
|
|
})
|
|
|
|
setupLegacyWebWorker(schedulerPtr, memory)
|
|
|
|
await run(schedulerPtr)
|
|
}
|
|
|
|
start().then(() => console.log("started via wasm"))
|
|
|
|
|