Skip to content

Conversation

vijaiaeroastro
Copy link

@vijaiaeroastro vijaiaeroastro commented Jun 17, 2025

  • This PR introduces WASM bindings for ACT.
  • The first version of this generator was originally implemented in Python: https://github.com/3MFConsortium/lib3mf_emscripten with the goal of creating WASM bindings for lib3mf.
  • The same functionality has now been ported and tested in ACT, and is designed to be generic and reusable.
  • All examples from the original lib3mf_emscripten repository work seamlessly with the bindings generated via ACT.

Key Features

  • Automatically generates wrapper structs for each native struct.
  • Creates wrapper methods when a struct is used as a method argument.
  • Handles non-const reference parameters by generating alternate wrapper methods that return a JavaScript object (since direct manipulation of non-const refs is not supported by Emscripten).
  • Most functions that take Pointers to class objects use a wrapper class called classParam in ACT. We detect these and automatically make it work inside bindings. However, users can simply use pointers in Javascript. Here is an example
const gyroidFunction = model.AddImplicitFunction();
gyroidFunction.SetDisplayName("gyroid");

// Add input position
const inputPos = gyroidFunction.AddInput("pos", "position", lib3mf.eImplicitPortType.Vector);

// Add decompose vector node
const decomposePos = gyroidFunction.AddDecomposeVectorNode("decomposePos", "decompose pos", "group_a");
  
// Link both
gyroidFunction.AddLink(inputPos, decomposePos.GetInputA()); // <--- Note this line

In the highlighted line above AddLink is actually supposed to have a signature like this in Cpp

void CImplicitFunction::AddLink(classParam<CImplicitPort> pSource, classParam<CImplicitPort> pTarget)
{
  Lib3MFHandle hSource = pSource.GetHandle();
  Lib3MFHandle hTarget = pTarget.GetHandle();
  CheckError(lib3mf_implicitfunction_addlink(m_pHandle, hSource, hTarget));
}

However, this cannot be implicitly constructor in WASM. So, we have a wrapper like this

static void wrap_ImplicitFunction_AddLink(CImplicitFunction &self, PImplicitPort& Source, PImplicitPort& Target) {
    self.AddLink(classParam(Source), classParam(Target));
}

This is automatically generated for all functions making it easy to write JS friendly code.

Known Issues

  • classParam<T> is used in many methods in the volumetric extension.
  • callBack functions are not supported yet

Copy link

@3dJan 3dJan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

@gangatp gangatp requested a review from Copilot August 13, 2025 06:03
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces WASM (WebAssembly) bindings for ACT through Emscripten. The implementation allows automatic generation of JavaScript-friendly bindings from C++ implementations, making it easier to use ACT-generated components in web environments.

Key changes include:

  • Adds complete WASM binding generation functionality to ACT's code generation pipeline
  • Introduces wrapper generation for structs, classes, and methods to handle JavaScript interoperability
  • Provides build tooling and examples for compiling WASM bindings using Emscripten

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Source/buildbindingwasm.go Core WASM binding generator with struct wrappers, method wrappers, and Emscripten bindings
Source/automaticcomponenttoolkit.go Integration of WASM binding generation into ACT's main workflow
Examples/RTTI/RTTI_component/Examples/WASM/buildWASM.py Python build script for compiling WASM bindings using Emscripten
Examples/RTTI/RTTI_component/Bindings/WASM/rtti_bindings.cpp Generated WASM binding file demonstrating the output
Examples/RTTI/RTTI.xml Configuration update to enable WASM binding generation
Build/build.sh Build script update to include the new WASM binding source file

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Collaborator

@gangatp gangatp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Vijai, overall looks good, check the comments from me and copilot. The one regarding indices looks doubtful. If its possible, it can be improved by adding error handling, input and output validations.

Regarding the return type and resolveCppType: is it always string from/to javascript? Is anyother type possible?

Also the binding implementation skips ImportedComponentDefinitions . Do you think it can be added later if its feasible?

@vijaiaeroastro
Copy link
Author

Hi Vijai, overall looks good, check the comments from me and copilot. The one regarding indices looks doubtful. If its possible, it can be improved by adding error handling, input and output validations.

Regarding the return type and resolveCppType: is it always string from/to javascript? Is anyother type possible?

Also the binding implementation skips ImportedComponentDefinitions . Do you think it can be added later if its feasible?

Only string and bool are handled in resolveCppType. The else case deals with everything else. Everything isn't a string.

@vijaiaeroastro
Copy link
Author

Hi Vijai, overall looks good, check the comments from me and copilot. The one regarding indices looks doubtful. If its possible, it can be improved by adding error handling, input and output validations.

Regarding the return type and resolveCppType: is it always string from/to javascript? Is anyother type possible?

Also the binding implementation skips ImportedComponentDefinitions . Do you think it can be added later if its feasible?

Yes, it can be added later.

@vijaiaeroastro
Copy link
Author

@gangatp All of the comments in the PR have been addressed. The rest of the improvements can be made in future.

@vijaiaeroastro
Copy link
Author

@gangatp Now ACT generates a minimal example for WASM in line with other bindings. I have also included a relevant build script for WASM and included a more useful example. All of them run locally without issues.

@vijaiaeroastro
Copy link
Author

@gangatp I have also modified the Dockerfile for GitHub Actions. WASM examples are also built now by GitHub Actions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants