Skip to content

Commit

Permalink
Started separating WASM into its own npm package
Browse files Browse the repository at this point in the history
  • Loading branch information
dpar39 committed Sep 25, 2023
1 parent cfa8033 commit 358e438
Show file tree
Hide file tree
Showing 16 changed files with 586 additions and 102 deletions.
12 changes: 9 additions & 3 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,24 @@ build:wasm --cpu=wasm
build:wasm --crosstool_top=@emsdk//emscripten_toolchain:everything
build:wasm --host_crosstool_top=@bazel_tools//tools/cpp:toolchain

build:wasm --cxxopt=-Os
build:wasm --cxxopt=-Wno-deprecated-builtins
build:wasm --cxxopt=-Wno-implicit-const-int-float-conversion
build:wasm --cxxopt=-Wno-unused-private-field
build:wasm --cxxopt=-Wno-deprecated-non-prototype
build:wasm --cxxopt=-fexceptions

build:wasm --copt=-sUSE_PTHREADS=0
build:wasm --features=exceptions
build:wasm --copt=-Os
build:wasm --copt=-sUSE_PTHREADS=0
build:wasm --copt=-fexceptions

build:wasm --linkopt=-sUSE_PTHREADS=0
build:wasm --linkopt=-Os
build:wasm --linkopt=--bind
build:wasm --linkopt=-fexceptions
build:wasm --linkopt=-sEXPORT_EXCEPTION_HANDLING_HELPERS=1
build:wasm --linkopt=-sUSE_PTHREADS=0
build:wasm --linkopt=-sMODULARIZE=1
build:wasm --linkopt=-sEXPORT_NAME=pppWasmApi
build:wasm --linkopt=-sINITIAL_MEMORY=134217728
build:wasm --linkopt=-sALLOW_MEMORY_GROWTH=1
build:wasm --linkopt=--preload-file=/src/mediapipe@/mediapipe
14 changes: 4 additions & 10 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/.vs
/env
CMakeLists.txt.user
/.vscode/.ropeproject
.bash_history
.ccache
Expand All @@ -15,9 +14,6 @@ explain.txt
# Build and install directories
/build_*
/install_*
/thirdparty/*
!/thirdparty/CMakeLists.txt
!/thirdparty/*.cmake

/node_modules
/research/*.asv
Expand All @@ -31,10 +27,6 @@ explain.txt
# Notes file
Notes.txt

# Generated assets
libppp/swig/*.cxx
libppp/share/config.bundle.json

tests-report.xml

### Added by Hedron's Bazel Compile Commands Extractor: https://github.com/hedronvision/bazel-compile-commands-extractor
Expand All @@ -47,5 +39,7 @@ compile_commands.json
# Directory where clangd puts its indexing work
.cache/



*.tsbuildinfo
.rollup.cache/
/package-lock.json
/dist/
12 changes: 9 additions & 3 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,14 @@
"group": "build"
},
{
"label": "x64: Refresh Compile Commands",
"command": "npm run compdb:native:dbg",
"label": "compdb: native",
"command": "npm run compdb:native",
"type": "shell",
"group": "build"
},
{
"label": "compdb: wasm",
"command": "npm run compdb:native",
"type": "shell",
"group": "build"
},
Expand Down Expand Up @@ -108,7 +114,7 @@
},
{
"label": "Web: Build",
"command": "run gen-app-info && run gen-pwa-icons && npx ionic build --prod",
"command": "npx gen-app-info && npx gen-pwa-icons && npx ionic build --prod",
"options": {
"cwd": "${workspaceFolder}/webapp"
},
Expand Down
21 changes: 9 additions & 12 deletions BUILD
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
load("@hedron_compile_commands//:refresh_compile_commands.bzl", "refresh_compile_commands")

refresh_compile_commands(
name = "refresh_compile_commands",

# Specify the targets of interest.
# For example, specify a dict of targets and any flags required to build.
name = "compdb_native",
targets = {
"//:ppp_test": "-c dbg",
}
)
refresh_compile_commands(
name = "compdb_wasm",
targets = {
#"//:ppp-wasm": "-c opts--config=wasm",
"//:ppp_test": "",
},
# No need to add flags already in .bazelrc. They're automatically picked up.
# If you don't need flags, a list of targets is also okay, as is a single target string.
# Wildcard patterns, like //... for everything, *are* allowed here, just like a build.
# As are additional targets (+) and subtractions (-), like in bazel query https://docs.bazel.build/versions/main/query.html#expressions
# And if you're working on a header-only library, specify a test or binary target that compiles it.
"//:ppp-wasm": "-c dbg --config=wasm",
}
)

load("@rules_cc//cc:defs.bzl", "cc_binary")
Expand Down
8 changes: 5 additions & 3 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ source $REPO_ROOT/dock.sh "$*"
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

TARGET=$1
if [[ "$TARGET" == "compdb" ]]; then
bazel --output_user_root=$REPO_ROOT/.bazel run :refresh_compile_commands -- -c dbg
if [[ "$TARGET" == "compdb:native" ]]; then
bazel --output_user_root=$REPO_ROOT/.bazel run :compdb_native
elif [[ "$TARGET" == "compdb:wasm" ]]; then
bazel --output_user_root=$REPO_ROOT/.bazel run :compdb_wasm
elif [[ "$TARGET" == "native:debug" ]]; then
bazel --output_user_root=$REPO_ROOT/.bazel build -c dbg //:ppp_test
elif [[ "$TARGET" == "native:release" ]]; then
Expand All @@ -19,5 +21,5 @@ elif [[ "$TARGET" == "wasm:debug" ]]; then
elif [[ "$TARGET" == "wasm:release" ]]; then
bazel --output_user_root=$REPO_ROOT/.bazel build -c opt //:ppp-wasm-wrap --config=wasm
else
_fail_ 'Usage: ./build.sh [compdb|native:debug|native:release|wasm:debug|wasm:release]'
_fail_ 'Usage: ./build.sh [compdb:native | compdb:wasm | native:debug | native:release | wasm:debug | wasm:release]'
fi
9 changes: 3 additions & 6 deletions dock.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
set -vx
set -e

_run_() { echo -e "\033[0;33m$*\033[0m"; $*; }
_info_() { echo -e "\033[1;34m$*\033[0m"; }
Expand All @@ -16,15 +16,12 @@ if [ ! -f /.dockerenv ]; then
REPO_ROOT="$(cd $DOCK_DIR &> /dev/null && pwd)"
SCRIPT_DIR_REL=$(realpath --relative-to=$REPO_ROOT "$PWD")

# --load \
# --cache-from type=local,src=$DOCK_DIR/.buildx-cache \
# --cache-to type=local,dest=$DOCK_DIR/.buildx-cache-new \
if [ -z ${SKIP_DOCKER_BUILD+x} ]; then
docker build --progress=plain -t docker-ci -f $DOCK_DIR/Dockerfile.builder \
_run_ docker build --progress=plain -t docker-ci -f $DOCK_DIR/Dockerfile.builder \
--build-arg "USER_NAME=$(whoami)" \
--build-arg "USER_UID=$(id -u)" \
--build-arg "USER_GID=$(id -g)" \
"$DOCK_DIR" >/dev/null
"$DOCK_DIR"
fi

if [ -t 1 ] ; then IT_ARGS=-it; else IT_ARGS= ; fi
Expand Down
143 changes: 143 additions & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import workerInitialize from './worker';
import { PppApi } from './types';

declare const process: any;
declare const require: any;

// Make sure only one web worker instance is created
// regardless of how many times package initialization is requested
type InitCallback = (v3d: PppApi) => void;
let workerInitializing = false;
let resolvedApi: PppApi;
let pendingInitRequests: InitCallback[] = [];

export default function (...args): Promise<PppApi> {
const debugLog = args[0] || true;
const profileLog = args[1] || false;
function debug(...args) {
if (debugLog) {
console.log('main:', ...args);
}
}

function initWebWorker() {
workerInitializing = true;
const isBrowser = !(typeof process === 'object' && typeof require === 'function');
const startTime = new Date().valueOf();
debug('starting new web worker...');

const prefixOverride = isBrowser
? window.location.href.replace(/(.+\w\/)(.+)/, '/$2')
: __dirname + '/';
let worker: any;
const workerCode = `(${workerInitialize.toString().trim()})(${debugLog},"${prefixOverride}");`;
if (isBrowser) {
const objectUrl = URL.createObjectURL(new Blob([workerCode], { type: 'text/javascript' }));
worker = new window.Worker(objectUrl);
URL.revokeObjectURL(objectUrl);
} else {
console.log(`${__dirname}`);
const { Worker } = require('node:worker_threads');
worker = new Worker(workerCode, { eval: true });
}

let callId = 0;
const pendingPromises = new Map();
let asyncApi: PppApi | object;

function makeAsyncFunction(methodName: string) {
return async function (...args: any) {
if (typeof this === 'object' && this.hasOwnProperty('__handle')) {
args.unshift(this.__handle);
}
return new Promise((accept, reject) => {
const currentId = callId++;
debug(`calling ${methodName}:${currentId}`);
pendingPromises.set(currentId, [accept, reject, methodName, new Date()]);
worker.postMessage({
method: methodName,
args: args.map((a) =>
typeof a === 'object' && a.hasOwnProperty('__handle') ? a.__handle : a
),
callId: currentId,
});
});
};
}

function makeAsyncApi(api: object) {
asyncApi = {
terminate: () => worker.terminate(),
};
for (let name in api) {
if (typeof api[name] == 'object') {
const className = name;
asyncApi[className] = {
create: makeAsyncFunction(`${className}$create`),
delete: makeAsyncFunction(`${className}$delete`),
};
for (let methodName in api[className]) {
asyncApi[className][methodName] = makeAsyncFunction(`${className}$${methodName}`);
}
} else {
asyncApi[name] = makeAsyncFunction(name);
}
}
return asyncApi;
}

function workerOnMessage(e) {
if (!e.data) {
return;
}
if (e.data.initialized && e.data.api) {
debug('worker has been initialized and ready');
makeAsyncApi(e.data.api);
debug(`worker initialized after ${new Date().valueOf() - startTime}ms`);
resolvedApi = asyncApi as PppApi;
for (let resolve of pendingInitRequests) {
resolve(resolvedApi);
}
pendingInitRequests = [];
} else {
const result = e.data.result;
if (
typeof result === 'object' &&
result.hasOwnProperty('__type') &&
asyncApi.hasOwnProperty(result.__type)
) {
result.__proto__ = asyncApi[result.__type];
}
const callId = e.data.callId;
const [acceptCb, rejectCb, methodName, startTime] = pendingPromises.get(callId);
if (profileLog) {
const elapsedMs = new Date().valueOf() - startTime;
console.log(`main: '${methodName}:${callId}' took ${elapsedMs}ms`);
}
if (e.data.success) {
acceptCb(e.data.result);
} else {
rejectCb(e.data.result);
}
pendingPromises.delete(e.data.callId);
}
}

if (isBrowser) {
worker.onmessage = workerOnMessage;
} else {
worker.on('message', workerOnMessage);
}
}
return new Promise((resolve) => {
if (resolvedApi) {
resolve(resolvedApi);
} else {
pendingInitRequests.push(resolve);
if (!workerInitializing) {
initWebWorker();
}
}
});
}
export * from './types';
10 changes: 10 additions & 0 deletions lib/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export interface PppEngine {

};

export interface PppApi {

getBuildTime(): Promise<string>;

terminate();
}
Loading

0 comments on commit 358e438

Please sign in to comment.