Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
474accb
Generates entirety of bindings from Python version (Uses ACT structur…
vijaiaeroastro Jun 9, 2025
4526f69
Bindings have been tested. They are in the same state as the ones cre…
vijaiaeroastro Jun 17, 2025
b7bbc90
Update static wrapper and out param wrapper to wrap more functions
vijaiaeroastro Jun 17, 2025
4b3361a
classParam is also properly detected and wrapped now. Implicit exampl…
vijaiaeroastro Jun 18, 2025
b7d7b2f
Some changes and possible bugs fixed (while implementing the RTTI exa…
vijaiaeroastro Jul 30, 2025
9b4d2ca
An automated build script that can build the base library and generat…
vijaiaeroastro Jul 30, 2025
a3773af
Push RTTI bindings + Updated XML
vijaiaeroastro Jul 30, 2025
de4dac7
Merge branch 'develop' into develop
gangatp Aug 6, 2025
6b9bce0
Its safer to use NameSpace instead of LibraryName as Library name can…
vijaiaeroastro Sep 3, 2025
c57705d
Merge branch 'develop' of github.com:vijaiaeroastro/AutomaticComponen…
vijaiaeroastro Sep 3, 2025
dd07e50
Fix file name
vijaiaeroastro Sep 3, 2025
b6c6663
Uncommented check from build.sh
vijaiaeroastro Sep 3, 2025
aa08a50
Fix transposed matrices
vijaiaeroastro Sep 3, 2025
261a11e
Working version of WASM build and run script
vijaiaeroastro Sep 3, 2025
bbc12bf
Allow example generation from WASM directly
vijaiaeroastro Sep 3, 2025
6455c72
Delete the monolith WASM build + example generator
vijaiaeroastro Sep 3, 2025
d3f494a
Add relevant entries in build scripts
vijaiaeroastro Sep 3, 2025
1965c29
Update dockerfile to also include emcc + basic changes
vijaiaeroastro Sep 3, 2025
f2e8171
Upgrade python version (emscripten uses walrus operator)
vijaiaeroastro Sep 3, 2025
a4be56f
Change default python version
vijaiaeroastro Sep 3, 2025
46db7fb
WASM needs 1 more library in docker image
vijaiaeroastro Sep 3, 2025
0068938
Merge branch 'develop' into develop
gangatp Sep 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 52 additions & 63 deletions Build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,81 +7,70 @@ LABEL maintainer="Andrii Anpilogov ([email protected])"

RUN [ -e /etc/yum.conf ] && sed -i '/tsflags=nodocs/d' /etc/yum.conf || true

# RUN yum install -y icu
# Vault repos for CentOS 8
RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* && \
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* && \
yum update -y

RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
RUN yum update -y
RUN dnf -y install dnf-plugins-core dnf-plugin-config-manager && dnf -y update
RUN dnf -y install epel-release && dnf -y config-manager --set-enabled powertools
RUN dnf -y install libatomic

RUN dnf -y install dnf-plugins-core
RUN dnf -y install dnf-plugin-config-manager
RUN dnf -y update
# Tooling
RUN dnf -y install gcc-toolset-9-gcc gcc-toolset-9-gcc-c++ cmake ninja-build git curl

RUN dnf -y install epel-release
RUN dnf -y config-manager --set-enabled powertools
# ---- Python 3.9 (required by recent emscripten) ----
RUN dnf -y module enable python39 && \
dnf -y install python39 python39-pip && \
alternatives --install /usr/bin/python3 python3 /usr/bin/python3.9 2 && \
alternatives --set python3 /usr/bin/python3.9

# GCC
RUN dnf -y install gcc-toolset-9-gcc
RUN dnf -y install gcc-toolset-9-gcc-c++
# (optional) ICU runtime/headers if you need them
# RUN dnf -y install libicu libicu-devel

# CMake & Ninja
RUN dnf -y install cmake
RUN dnf -y install ninja-build

# Free Pascal
# 3.0.4 should be used for validating compiler base compatibility.
# Free Pascal 3.0.4
RUN (cd /opt && curl -O -L 'http://downloads.sourceforge.net/project/freepascal/Linux/3.0.4/fpc-3.0.4-1.x86_64.rpm' \
&& rpm -i fpc-3.0.4-1.x86_64.rpm)

# Using 3.2.2 until PolymorphicFactory is reworked to not using generics that are not full functional in 3.0.4.
# RUN (cd /opt && curl -O -L 'http://downloads.sourceforge.net/project/freepascal/Linux/3.2.2/fpc-3.2.2-1.x86_64.rpm' \
# && rpm -i fpc-3.2.2-1.x86_64.rpm)

# Golang
RUN (cd /opt && curl -O -L https://golang.org/dl/go1.17.2.linux-amd64.tar.gz \
&& tar zxvf go1.17.2.linux-amd64.tar.gz)

# Java
RUN dnf -y install \
java-11-openjdk-devel
# Go
RUN (cd /opt && curl -O -L https://golang.org/dl/go1.17.2.linux-amd64.tar.gz && tar zxvf go1.17.2.linux-amd64.tar.gz)
ENV PATH="${PATH}:/opt/go/bin"

# Mono
# Java & Mono
RUN dnf -y install java-11-openjdk-devel
RUN rpm --import https://download.mono-project.com/repo/xamarin.gpg \
&& dnf config-manager --add-repo https://download.mono-project.com/repo/centos8-stable.repo \
&& dnf -y install mono-complete

# General purpose tools
RUN dnf -y install \
glibc-common \
glibc-utils \
less \
passwd \
tar \
vim-minimal \
vim-enhanced \
which \
sudo \
bash-completion \
mc \
yum-utils \
&& yum clean all

# # Initialize Toolkit
RUN echo "source /opt/rh/gcc-toolset-9/enable" >> /etc/bashrc
ENV PATH="${PATH}:/opt/go/bin"

# Initialize Toolkit
# RUN : "${USER_ID:?Build argument needs to be set and non-empty.}" \
# : "${GROUP_ID:?Build argument needs to be set and non-empty.}"
# General tools
RUN dnf -y install glibc-common glibc-utils less passwd tar vim-minimal vim-enhanced which sudo bash-completion mc yum-utils && yum clean all

# Create user
RUN if [ $USER_ID != "" ] ; then groupadd docker \
&& useradd -ms /bin/bash --uid $USER_ID -g docker -G wheel user \
&& printf "user:user" | chpasswd \
&& printf "user ALL= NOPASSWD: ALL\\n" >> /etc/sudoers ; fi

# Initialize Toolkit
RUN if [ $USER_ID != "" ] ; then echo "source /opt/rh/gcc-toolset-9/enable" >> /home/user/.bash_profile ; fi
RUN if [ $USER_ID != "" ] ; then echo "export PATH=\$PATH:/opt/go/bin" >> /home/user/.bash_profile ; fi
# Enable GCC toolset in shells
RUN echo "source /opt/rh/gcc-toolset-9/enable" >> /etc/bashrc

ENTRYPOINT ["./entrypoint.sh"]
# ---- Emscripten SDK (emsdk) ----
ENV EMSDK=/opt/emsdk
RUN git clone https://github.com/emscripten-core/emsdk.git ${EMSDK} && \
bash -lc "cd ${EMSDK} && ./emsdk install latest && ./emsdk activate latest"

# Source emsdk env in interactive shells
RUN echo "source ${EMSDK}/emsdk_env.sh" >> /etc/bashrc

# Create user (if requested)
RUN if [ -n "$USER_ID" ]; then \
groupadd -g ${GROUP_ID:-1000} docker && \
useradd -ms /bin/bash --uid $USER_ID -g docker -G wheel user && \
printf 'user:user' | chpasswd && \
printf 'user ALL= NOPASSWD: ALL\n' >> /etc/sudoers && \
echo 'source /opt/rh/gcc-toolset-9/enable' >> /home/user/.bash_profile && \
echo "export EMSDK_PYTHON=${EMSDK_PYTHON}" >> /home/user/.bash_profile && \
echo "source ${EMSDK}/emsdk_env.sh" >> /home/user/.bash_profile ; \
fi

# Sanity check (now python3 == 3.9; don't rely on EMSDK_PYTHON which emsdk_env clears)
RUN bash -lc "source ${EMSDK}/emsdk_env.sh && \
python3 --version && emcc --version && em++ --version && node --version && \
/opt/emsdk/upstream/bin/wasm-opt --version"

# Your repo should provide this script; it will source the env before running any command.
ENTRYPOINT ["./entrypoint.sh"]
2 changes: 1 addition & 1 deletion Build/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ startingpath="$(pwd)"
basepath="$(cd "$(dirname "$0")" && pwd)"
cd "$basepath/../Source"

Sources="actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbindingccppdocumentation.go buildbindingcsharp.go buildbindinggo.go buildbindingnode.go buildbindingpascal.go buildbindingpython.go buildbindingjava.go buildimplementationcpp.go buildimplementationpascal.go componentdefinition.go componentdiff.go languagewriter.go languagec.go languagecpp.go languagepascal.go"
Sources="actutils.go automaticcomponenttoolkit.go buildbindingccpp.go buildbindingccppdocumentation.go buildbindingcsharp.go buildbindinggo.go buildbindingnode.go buildbindingpascal.go buildbindingpython.go buildbindingwasm.go buildbindingjava.go buildimplementationcpp.go buildimplementationpascal.go componentdefinition.go componentdiff.go languagewriter.go languagec.go languagecpp.go languagepascal.go"

echo "Build act.win64.exe"
export GOARCH="amd64"
Expand Down
1 change: 1 addition & 0 deletions Examples/RTTI/RTTI.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<binding language="CSharp" indentation="tabs" />
<binding language="Go" indentation="tabs" />
<binding language="Java" indentation="tabs" />
<binding language="WASM" indentation="tabs" />
</bindings>

<implementations>
Expand Down
123 changes: 123 additions & 0 deletions Examples/RTTI/RTTI_component/Bindings/WASM/rtti_bindings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*++

Copyright (C) 2021 ADSK

All rights reserved.

This file has been generated by the Automatic Component Toolkit (ACT) version 1.8.0-develop.

Abstract: C++ Emscripten wrapper for WebAssembly

Interface version: 1.0.0

*/

#include <iostream>
#include <vector>
#include <string>
#include <emscripten.h>
#include <emscripten/bind.h>
#include "Cpp/rtti_implicit.hpp"

using namespace emscripten;
using namespace RTTI;

static void wrap_Wrapper_ReleaseInstance(CWrapper &self, PBase& Instance) {
self.ReleaseInstance(classParam(Instance));
}

static void wrap_Wrapper_AcquireInstance(CWrapper &self, PBase& Instance) {
self.AcquireInstance(classParam(Instance));
}

static emscripten::val wrap_AnimalIterator_GetNextOptinalAnimal(CAnimalIterator &self) {
emscripten::val output = emscripten::val::object();
PAnimal Animal;
bool return_value = self.GetNextOptinalAnimal(Animal);
output.set("return", return_value);
output.set("Animal", Animal);
return output;
}

static emscripten::val wrap_AnimalIterator_GetNextMandatoryAnimal(CAnimalIterator &self) {
emscripten::val output = emscripten::val::object();
PAnimal Animal;
bool return_value = self.GetNextMandatoryAnimal(Animal);
output.set("return", return_value);
output.set("Animal", Animal);
return output;
}

static emscripten::val wrap_Wrapper_GetVersion(CWrapper &self) {
emscripten::val output = emscripten::val::object();
RTTI_uint32 Major;
RTTI_uint32 Minor;
RTTI_uint32 Micro;
self.GetVersion(Major, Minor, Micro);
output.set("Major", Major);
output.set("Minor", Minor);
output.set("Micro", Micro);
return output;
}

static emscripten::val wrap_Wrapper_GetLastError(CWrapper &self, PBase& Instance) {
emscripten::val output = emscripten::val::object();
std::string ErrorMessage;
bool return_value = self.GetLastError(classParam(Instance), ErrorMessage);
output.set("return", return_value);
output.set("ErrorMessage", ErrorMessage);
return output;
}

// ================== Emscripten Bindings ==================
EMSCRIPTEN_BINDINGS(RTTI) {
// Binding Methods
class_<CBase>("CBase")
.smart_ptr<std::shared_ptr<CBase>>("shared_ptr<CBase>")
.function("ClassTypeId", &CBase::ClassTypeId)
;
class_<CAnimal, base<CBase>>("CAnimal")
.smart_ptr<std::shared_ptr<CAnimal>>("shared_ptr<CAnimal>")
.function("Name", &CAnimal::Name)
;
class_<CMammal, base<CAnimal>>("CMammal")
.smart_ptr<std::shared_ptr<CMammal>>("shared_ptr<CMammal>")
;
class_<CReptile, base<CAnimal>>("CReptile")
.smart_ptr<std::shared_ptr<CReptile>>("shared_ptr<CReptile>")
;
class_<CGiraffe, base<CMammal>>("CGiraffe")
.smart_ptr<std::shared_ptr<CGiraffe>>("shared_ptr<CGiraffe>")
;
class_<CTiger, base<CMammal>>("CTiger")
.smart_ptr<std::shared_ptr<CTiger>>("shared_ptr<CTiger>")
.function("Roar", &CTiger::Roar)
;
class_<CSnake, base<CReptile>>("CSnake")
.smart_ptr<std::shared_ptr<CSnake>>("shared_ptr<CSnake>")
;
class_<CTurtle, base<CReptile>>("CTurtle")
.smart_ptr<std::shared_ptr<CTurtle>>("shared_ptr<CTurtle>")
;
class_<CAnimalIterator>("CAnimalIterator")
.smart_ptr<std::shared_ptr<CAnimalIterator>>("shared_ptr<CAnimalIterator>")
.function("GetNextAnimal", &CAnimalIterator::GetNextAnimal)
.function("GetNextOptinalAnimal", &wrap_AnimalIterator_GetNextOptinalAnimal)
.function("GetNextMandatoryAnimal", &wrap_AnimalIterator_GetNextMandatoryAnimal)
;
class_<CZoo>("CZoo")
.smart_ptr<std::shared_ptr<CZoo>>("shared_ptr<CZoo>")
.function("Iterator", &CZoo::Iterator)
;
// CWrapper global bindings
class_<CWrapper>("CWrapper")
.constructor<>()
.function("GetVersion", &wrap_Wrapper_GetVersion)
.function("GetLastError", &wrap_Wrapper_GetLastError)
.function("ReleaseInstance", &wrap_Wrapper_ReleaseInstance)
.function("AcquireInstance", &wrap_Wrapper_AcquireInstance)
// .function("InjectComponent", &CWrapper::InjectComponent) // Explicitly skipped (Returns a void pointer)
// .function("GetSymbolLookupMethod", &CWrapper::GetSymbolLookupMethod) // Explicitly skipped (Returns a void pointer)
.function("CreateZoo", &CWrapper::CreateZoo)
;
}
75 changes: 75 additions & 0 deletions Examples/RTTI/RTTI_component/Examples/WASM/RTTI_Better_Example.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*++

Copyright (C) 2021 ADSK

All rights reserved.

This file has been generated by the Automatic Component Toolkit (ACT) version 1.8.1-develop.

Abstract: This is an autogenerated Node.js application that demonstrates the
usage of the WebAssembly bindings of RTTI

Interface version: 1.0.0

*/

import initModule from './rttiBinding.js';

function assert(cond, msg) {
if (!cond) throw new Error(msg || 'Assertion failed');
}

try {
console.log('Running RTTI WASM Example…');

const mod = await initModule(); // MODULARIZE + EXPORT_ES6
console.log('✅ module initialized');

const wrapper = new mod.CWrapper();
const { Major, Minor, Micro } = wrapper.GetVersion();
console.log(`RTTI version: ${Major}.${Minor}.${Micro}`);

const zoo = wrapper.CreateZoo();
assert(zoo, 'Failed to create Zoo');

const iter = zoo.Iterator();
assert(iter, 'Failed to create Iterator');

let animal;
let animalCount = 0;

while ((animal = iter.GetNextAnimal())) {
animalCount++;
const name = animal.Name();
console.log(`Processing animal #${animalCount}: ${name}`);

if (name === 'Gerald Giraffe' || name === 'Gary Giraffe') {
assert(animal instanceof mod.CGiraffe, `Expected ${name} to be a Giraffe`);
} else if (name === 'Timmy Tiger' || name === 'Tony Tiger' || name === 'Travis Tiger') {
assert(animal instanceof mod.CTiger, `Expected ${name} to be a Tiger`);
animal.Roar();
} else if (name === 'Sebastian Snake' || name === 'Slytherin Snake') {
assert(animal instanceof mod.CSnake, `Expected ${name} to be a Snake`);
} else if (name.includes('Turtle')) {
assert(animal instanceof mod.CTurtle, `Expected ${name} to be a Turtle`);
} else {
console.warn(`Unknown animal type for ${name}`);
}

animal.delete(); // free embind wrapper
}

// Iterator should be exhausted now
const noMore = iter.GetNextAnimal();
assert(!noMore, 'Iterator should be exhausted after the loop');
if (noMore) noMore.delete();

console.log(`\n✅ Successfully processed ${animalCount} animals.`);

iter.delete();
zoo.delete();
wrapper.delete();
} catch (err) {
console.error('Error:', err);
process.exit(1);
}
30 changes: 30 additions & 0 deletions Examples/RTTI/RTTI_component/Examples/WASM/RTTI_Example.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*++

Copyright (C) 2021 ADSK

All rights reserved.

This file has been generated by the Automatic Component Toolkit (ACT) version 1.8.1-develop.

Abstract: This is an autogenerated Node.js application that demonstrates the
usage of the WebAssembly bindings of RTTI

Interface version: 1.0.0

*/

// Autogenerated minimal ES module example for RTTI WASM
// Run with: node example.mjs

import initModule from './rttiBinding.js';

console.log('Running RTTI WASM Example...');

const mod = await initModule(); // MODULARIZE + EXPORT_ES6 default export
console.log('✅ RTTI WASM module initialized');

const wrapper = new mod.CWrapper();
const { Major, Minor, Micro } = wrapper.GetVersion();
console.log('RTTI version: ' + Major + '.' + Minor + '.' + Micro);

// TODO: add component-specific demo calls here
Loading
Loading