From f3cc1c8d8f338aac8959fad08097891bbced1e85 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 9 Jul 2024 11:38:54 -0300 Subject: [PATCH 001/186] Update workflow tag --- .github/workflows/build_and_upload.yml | 29 +++++++++++++++++++- .github/workflows/tag.yml | 38 -------------------------- 2 files changed, 28 insertions(+), 39 deletions(-) delete mode 100644 .github/workflows/tag.yml diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index ef89fb82..83ae71f2 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -257,6 +257,14 @@ jobs: - name: Generate Java classes run: ./gradlew build_project + - name: Get version + uses: madhead/read-java-properties@latest + id: version + with: + file: "./gradle.properties" + property: version + default: 0.0.1 + - name: Upload to repository uses: nick-fields/retry@v3 with: @@ -268,4 +276,23 @@ jobs: USER: ${{ secrets.USER }} PASSWORD: ${{ secrets.PASSWORD }} SIGNING_KEY: ${{ secrets.PGP_SECRET }} - SIGNING_PASSWORD: ${{ secrets.PGP_PASSPHRASE }} \ No newline at end of file + SIGNING_PASSWORD: ${{ secrets.PGP_PASSPHRASE }} + + - name: Create Git tag + uses: actions/github-script@v7 + if: ${{ success() && inputs.isRelease == 'true' }} + with: + script: | + const versionOutputs = ${{ toJSON(steps.version.outputs) }}; + + var version = versionOutputs.value; + + console.log("Version: " + version); + + var ref = "refs/tags/" + version + github.rest.git.createRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: ref, + sha: context.sha + }); \ No newline at end of file diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml deleted file mode 100644 index a6ae966f..00000000 --- a/.github/workflows/tag.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Create Tag - -on: - push: - branches: - - 'release' - -jobs: - add-tag: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - uses: madhead/read-java-properties@latest - id: version - with: - file: "./gradle.properties" - property: version - default: 0.0.1 - - - name: Create Git tag - uses: actions/github-script@v7 - with: - script: | - const versionOutputs = ${{ toJSON(steps.version.outputs) }}; - - var version = versionOutputs.value; - - console.log("Version: " + version); - - var ref = "refs/tags/" + version - github.rest.git.createRef({ - owner: context.repo.owner, - repo: context.repo.repo, - ref: ref, - sha: context.sha - }); \ No newline at end of file From 63283844f5cb5694d1a4c2ceaf4ea0663caba875 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 9 Jul 2024 11:46:21 -0300 Subject: [PATCH 002/186] Update workflow --- .github/workflows/build_and_upload.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 83ae71f2..77ff8940 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -267,6 +267,7 @@ jobs: - name: Upload to repository uses: nick-fields/retry@v3 + if: ${{ success() && inputs.shouldUpload == 'true' }} with: max_attempts: 3 timeout_minutes: 10 From 01e358201f9df23e47d0408ceb384b24eb4f60c9 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 9 Jul 2024 11:57:02 -0300 Subject: [PATCH 003/186] Update workflow --- .github/workflows/build_and_upload.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 77ff8940..c4263063 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -211,6 +211,14 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Get version + uses: madhead/read-java-properties@latest + id: version + with: + file: "./gradle.properties" + property: version + default: 0.0.1 + - name: Set up JDK 11 uses: actions/setup-java@v4 with: @@ -257,14 +265,6 @@ jobs: - name: Generate Java classes run: ./gradlew build_project - - name: Get version - uses: madhead/read-java-properties@latest - id: version - with: - file: "./gradle.properties" - property: version - default: 0.0.1 - - name: Upload to repository uses: nick-fields/retry@v3 if: ${{ success() && inputs.shouldUpload == 'true' }} From 6434434091afb65c740b6c0c6276eb4badc9b062 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 9 Jul 2024 12:04:41 -0300 Subject: [PATCH 004/186] Update workflow --- .github/workflows/build_and_upload.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index c4263063..b1892e39 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -267,7 +267,7 @@ jobs: - name: Upload to repository uses: nick-fields/retry@v3 - if: ${{ success() && inputs.shouldUpload == 'true' }} + if: (success()) && ${{ inputs.shouldUpload == 'true' }} with: max_attempts: 3 timeout_minutes: 10 From 9921647f8498af0690f73977daa25bc5eda9190e Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 9 Jul 2024 12:09:58 -0300 Subject: [PATCH 005/186] Update workflow --- .github/workflows/dispatch_build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dispatch_build.yml b/.github/workflows/dispatch_build.yml index c3e4fc9b..0c0f8253 100644 --- a/.github/workflows/dispatch_build.yml +++ b/.github/workflows/dispatch_build.yml @@ -6,10 +6,13 @@ on: isRelease: required: true type: boolean + shouldUpload: + required: true + type: boolean jobs: build-and-upload: uses: ./.github/workflows/build_and_upload.yml with: isRelease: ${{ inputs.isRelease }} - shouldUpload: true + shouldUpload: ${{ inputs.shouldUpload }} secrets: inherit \ No newline at end of file From f8f2a499e57cba73f56f84a70d40466ae4746bbd Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 9 Jul 2024 12:13:19 -0300 Subject: [PATCH 006/186] Update workflow --- .github/workflows/dispatch_build.yml | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dispatch_build.yml b/.github/workflows/dispatch_build.yml index 0c0f8253..7eb52614 100644 --- a/.github/workflows/dispatch_build.yml +++ b/.github/workflows/dispatch_build.yml @@ -11,8 +11,25 @@ on: type: boolean jobs: build-and-upload: - uses: ./.github/workflows/build_and_upload.yml - with: - isRelease: ${{ inputs.isRelease }} - shouldUpload: ${{ inputs.shouldUpload }} - secrets: inherit \ No newline at end of file +# uses: ./.github/workflows/build_and_upload.yml +# with: +# isRelease: ${{ inputs.isRelease }} +# shouldUpload: ${{ inputs.shouldUpload }} +# secrets: inherit +# + runs-on: ubuntu-latest + steps: + + - name: Test Release + uses: actions/github-script@v7 + if: ${{ inputs.shouldUpload == 'true' }} + with: + script: | + console.log("LOG shouldUpload"); + + - name: Test Release + uses: actions/github-script@v7 + if: ${{ inputs.isRelease == 'true' }} + with: + script: | + console.log("LOG RELEASE"); \ No newline at end of file From d5f183e1713ee300bdcec57b75a43ca60d76d90f Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 9 Jul 2024 12:13:53 -0300 Subject: [PATCH 007/186] Update workflow --- .github/workflows/dispatch_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dispatch_build.yml b/.github/workflows/dispatch_build.yml index 7eb52614..1405d976 100644 --- a/.github/workflows/dispatch_build.yml +++ b/.github/workflows/dispatch_build.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - - name: Test Release + - name: Test Upload uses: actions/github-script@v7 if: ${{ inputs.shouldUpload == 'true' }} with: From 578559c7dc57f3f75c0c3599bc3295d019683a87 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 9 Jul 2024 12:14:56 -0300 Subject: [PATCH 008/186] Update workflow --- .github/workflows/dispatch_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dispatch_build.yml b/.github/workflows/dispatch_build.yml index 1405d976..7cc50155 100644 --- a/.github/workflows/dispatch_build.yml +++ b/.github/workflows/dispatch_build.yml @@ -22,7 +22,7 @@ jobs: - name: Test Upload uses: actions/github-script@v7 - if: ${{ inputs.shouldUpload == 'true' }} + if: ${{ inputs.shouldUpload }} with: script: | console.log("LOG shouldUpload"); From 6d08eeb4e7bcd488130dda80cce3098b1af4ab56 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 9 Jul 2024 12:16:25 -0300 Subject: [PATCH 009/186] Update workflow --- .github/workflows/dispatch_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dispatch_build.yml b/.github/workflows/dispatch_build.yml index 7cc50155..ff387580 100644 --- a/.github/workflows/dispatch_build.yml +++ b/.github/workflows/dispatch_build.yml @@ -29,7 +29,7 @@ jobs: - name: Test Release uses: actions/github-script@v7 - if: ${{ inputs.isRelease == 'true' }} + if: ${{ inputs.isRelease }} with: script: | console.log("LOG RELEASE"); \ No newline at end of file From 88885271f1fcd138c195749460d283b94f6ca02e Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 9 Jul 2024 12:18:06 -0300 Subject: [PATCH 010/186] Update workflow --- .github/workflows/build_and_upload.yml | 4 ++-- .github/workflows/dispatch_build.yml | 27 +++++--------------------- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index b1892e39..74451614 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -267,7 +267,7 @@ jobs: - name: Upload to repository uses: nick-fields/retry@v3 - if: (success()) && ${{ inputs.shouldUpload == 'true' }} + if: ${{ inputs.shouldUpload }} with: max_attempts: 3 timeout_minutes: 10 @@ -281,7 +281,7 @@ jobs: - name: Create Git tag uses: actions/github-script@v7 - if: ${{ success() && inputs.isRelease == 'true' }} + if: ${{ inputs.isRelease }} with: script: | const versionOutputs = ${{ toJSON(steps.version.outputs) }}; diff --git a/.github/workflows/dispatch_build.yml b/.github/workflows/dispatch_build.yml index ff387580..755483f5 100644 --- a/.github/workflows/dispatch_build.yml +++ b/.github/workflows/dispatch_build.yml @@ -11,25 +11,8 @@ on: type: boolean jobs: build-and-upload: -# uses: ./.github/workflows/build_and_upload.yml -# with: -# isRelease: ${{ inputs.isRelease }} -# shouldUpload: ${{ inputs.shouldUpload }} -# secrets: inherit -# - runs-on: ubuntu-latest - steps: - - - name: Test Upload - uses: actions/github-script@v7 - if: ${{ inputs.shouldUpload }} - with: - script: | - console.log("LOG shouldUpload"); - - - name: Test Release - uses: actions/github-script@v7 - if: ${{ inputs.isRelease }} - with: - script: | - console.log("LOG RELEASE"); \ No newline at end of file + uses: ./.github/workflows/build_and_upload.yml + with: + isRelease: ${{ inputs.isRelease }} + shouldUpload: ${{ inputs.shouldUpload }} + secrets: inherit From 2652ede27497f3142bb121f68e5d6ec71e416d60 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 9 Jul 2024 13:00:47 -0300 Subject: [PATCH 011/186] Fix badge --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b54925ee..d251b274 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ ![Build](https://github.com/xpenatan/jParser/actions/workflows/release.yml/badge.svg) ![Build](https://github.com/xpenatan/jParser/actions/workflows/snapshot.yml/badge.svg) -[![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/r/com.github.xpenatan.jParser/jParser-core?nexusVersion=2&server=https%3A%2F%2Foss.sonatype.org&label=release)](https://repo.maven.apache.org/maven2/com/github/xpenatan/jParser/) -[![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/com.github.xpenatan.jParser/jParser-core?server=https%3A%2F%2Foss.sonatype.org&label=snapshot)](https://oss.sonatype.org/content/repositories/snapshots/com/github/xpenatan/jParser/) +[![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/releases/com.github.xpenatan.jParser/jParser-core?nexusVersion=2&server=https%3A%2F%2Foss.sonatype.org&label=release)](https://repo.maven.apache.org/maven2/com/github/xpenatan/jParser/) +![Static Badge](https://img.shields.io/badge/snapshot---SNAPSHOT-red)(https://oss.sonatype.org/content/repositories/snapshots/com/github/xpenatan/jParser/) ## jParser From f94cd0eb618316aac857787fcb4bbbaeeb3434f5 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 9 Jul 2024 13:03:03 -0300 Subject: [PATCH 012/186] Fix badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d251b274..133932e2 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![Build](https://github.com/xpenatan/jParser/actions/workflows/snapshot.yml/badge.svg) [![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/releases/com.github.xpenatan.jParser/jParser-core?nexusVersion=2&server=https%3A%2F%2Foss.sonatype.org&label=release)](https://repo.maven.apache.org/maven2/com/github/xpenatan/jParser/) -![Static Badge](https://img.shields.io/badge/snapshot---SNAPSHOT-red)(https://oss.sonatype.org/content/repositories/snapshots/com/github/xpenatan/jParser/) +[![Static Badge](https://img.shields.io/badge/snapshot---SNAPSHOT-red)](https://oss.sonatype.org/content/repositories/snapshots/com/github/xpenatan/jParser/) ## jParser From ae44ff2faa746f4f7e15915a226b39879e450857 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 9 Jul 2024 13:10:21 -0300 Subject: [PATCH 013/186] Fix badge --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 133932e2..88d0902e 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,10 @@ +## jParser + ![Build](https://github.com/xpenatan/jParser/actions/workflows/release.yml/badge.svg) ![Build](https://github.com/xpenatan/jParser/actions/workflows/snapshot.yml/badge.svg) - [![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/releases/com.github.xpenatan.jParser/jParser-core?nexusVersion=2&server=https%3A%2F%2Foss.sonatype.org&label=release)](https://repo.maven.apache.org/maven2/com/github/xpenatan/jParser/) [![Static Badge](https://img.shields.io/badge/snapshot---SNAPSHOT-red)](https://oss.sonatype.org/content/repositories/snapshots/com/github/xpenatan/jParser/) - -## jParser jParser is a small Java library that helps bind C/C++ code to desktop, mobile, and the web, allowing it to be written inline with Java source code. It was inspired by [gdx-jnigen](https://github.com/libgdx/gdx-jnigen) that you add a native code into a code block. This code block will be translated to the specific code target. You can add multiple code block targets in the same java source. For each code target, it will generate a new java source code. From 22a9ec6e5fd25499a7c35532bfe78238d1981e86 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 9 Jul 2024 13:13:57 -0300 Subject: [PATCH 014/186] fix readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 88d0902e..d00c8fa2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## jParser +# jParser ![Build](https://github.com/xpenatan/jParser/actions/workflows/release.yml/badge.svg) ![Build](https://github.com/xpenatan/jParser/actions/workflows/snapshot.yml/badge.svg) From c48d033a0addf610e319e12d23354c42a02e2c5a Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 9 Jul 2024 13:17:55 -0300 Subject: [PATCH 015/186] fix readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d00c8fa2..ec972f1f 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ It's not 100%, but it will reduce the amount of work binding big libraries. You Libraries usisng jParser:
- [gdx-imgui](https://github.com/xpenatan/gdx-imgui) - [gdx-lua](https://github.com/xpenatan/gdx-lua) +- [gdx-jolt](https://github.com/xpenatan/gdx-jolt) - [gdx-bullet](https://github.com/xpenatan/gdx-bullet) - [gdx-physx](https://github.com/xpenatan/gdx-physx) - [gdx-box2d](https://github.com/xpenatan/gdx-box2d) From f4234ccf61b1d6395490971156647c5929c941bf Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 30 Jul 2024 00:04:45 -0300 Subject: [PATCH 016/186] add mac target option --- .../xpenatan/jparser/builder/targets/MacTarget.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java index 5a18756e..0cbea7a2 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java @@ -9,12 +9,19 @@ public class MacTarget extends DefaultBuildTarget { private boolean isArm = false; + private final String macMinTarget; + public MacTarget() { this(false); } public MacTarget(boolean isArm) { + this(isArm, "10.7"); + } + + public MacTarget(boolean isArm, String macMinTarget) { this.isArm = isArm; + this.macMinTarget = macMinTarget; if(isArm) { this.libDirSuffix = "mac/arm/"; @@ -54,7 +61,7 @@ public MacTarget(boolean isArm) { cppFlags.add("-w"); cppFlags.add("-Wno-format"); - cppFlags.add("-mmacosx-version-min=10.7"); + cppFlags.add("-mmacosx-version-min=" + macMinTarget); cppFlags.add("-stdlib=libc++"); } @@ -79,7 +86,7 @@ protected void setup(BuildConfig config) { cppFlags.add("x86_64"); libSuffix = "64.dylib"; } - linkerFlags.add("-mmacosx-version-min=10.7"); + linkerFlags.add("-mmacosx-version-min=" + macMinTarget); linkerFlags.add("-stdlib=libc++"); } } From a2918569b8ad5ad0608014ca9bde52a07846cbaf Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 30 Jul 2024 00:07:01 -0300 Subject: [PATCH 017/186] update min target --- .../com/github/xpenatan/jparser/builder/targets/MacTarget.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java index 0cbea7a2..4a1460b5 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java @@ -16,7 +16,7 @@ public MacTarget() { } public MacTarget(boolean isArm) { - this(isArm, "10.7"); + this(isArm, "10.12"); } public MacTarget(boolean isArm, String macMinTarget) { From e6ed9582a8222ede0948778ef663f20f51d2ee59 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 30 Jul 2024 08:14:51 -0300 Subject: [PATCH 018/186] add android c++17 --- .../github/xpenatan/jparser/builder/targets/AndroidTarget.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java index 69c74a66..b0d5c67e 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java @@ -20,6 +20,7 @@ public AndroidTarget() { cppFlags.add("-Wall"); cppFlags.add("-D__ANDROID__"); cppFlags.add("-fvisibility=hidden"); + cppFlags.add("-std=c++17"); linkerFlags.add("-lm"); cppInclude.add("**/jniglue/JNIGlue.cpp"); From 42e0c762898f586aadfd6b1fe3694428fc044602 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 30 Jul 2024 08:30:42 -0300 Subject: [PATCH 019/186] add android custom args --- .../github/xpenatan/jparser/builder/targets/AndroidTarget.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java index b0d5c67e..3094b1f4 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java @@ -12,6 +12,8 @@ public class AndroidTarget extends DefaultBuildTarget { public String androidABIS = "all"; public String androidPlatform = "android-19"; + public ArrayList customArgs = new ArrayList<>(); + public AndroidTarget() { this.libDirSuffix = "android/"; this.tempBuildDir = "target/android"; @@ -108,6 +110,7 @@ protected boolean build(BuildConfig config) { CustomFileDescriptor childTarget = config.libDir.child("android"); ArrayList commands = new ArrayList<>(); commands.add(androidCommand); + commands.addAll(customArgs); commands.add("NDK_PROJECT_PATH=."); commands.add("NDK_APPLICATION_MK=Application.mk"); commands.add(" NDK_LIBS_OUT=" + childTarget.path()); From 5ba275ab6766e56b0f1ea7659dcaa7bc243c350c Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 30 Jul 2024 09:23:46 -0300 Subject: [PATCH 020/186] wip multicore compile --- .../jparser/builder/DefaultBuildTarget.java | 60 ++++++++++++++++--- .../builder/targets/AndroidTarget.java | 5 ++ 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java index de1e59db..4536f414 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java @@ -5,9 +5,14 @@ import java.nio.file.Path; import java.nio.file.PathMatcher; import java.util.ArrayList; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; public abstract class DefaultBuildTarget extends BuildTarget { + public boolean multiCoreCompile = true; + public String tempBuildDir; private final ArrayList compilerCommands = new ArrayList<>(); @@ -83,15 +88,52 @@ private boolean compile(BuildConfig config, CustomFileDescriptor childTarget, Ar CustomFileDescriptor cppList = childTarget.child("cpp.txt"); cppList.writeString(compiledPaths.trim(), false); - compilerCommands.clear(); - compilerCommands.addAll(cppCompiler); - compilerCommands.addAll(cppFlags); - compilerCommands.addAll(headerDirs); - compilerCommands.add("@" + cppList.path()); - System.err.println("##### COMPILE #####"); - boolean flag = JProcess.startProcess(config.buildDir.file(), compilerCommands); - if(!flag) { - return false; + if(multiCoreCompile) { + System.err.println("##### COMPILE #####"); + + int threads = Runtime.getRuntime().availableProcessors(); + ExecutorService executorService = Executors.newFixedThreadPool(threads); + ArrayList> futures = new ArrayList<>(); + + for(CustomFileDescriptor file : cppFiles) { + String path = file.path(); + + Future submit = executorService.submit(() -> { + ArrayList threadCommands = new ArrayList<>(); + threadCommands.addAll(cppCompiler); + threadCommands.addAll(cppFlags); + threadCommands.addAll(headerDirs); + threadCommands.add(path); + boolean flag = JProcess.startProcess(config.buildDir.file(), threadCommands); + if(!flag) { + throw new RuntimeException("Compile Error"); + } + }); + futures.add(submit); + } + + for (Future future : futures) { + try { + future.get(); + } catch (Exception e) { + e.printStackTrace(); + executorService.shutdown(); + return false; + } + } + executorService.shutdown(); + } + else { + compilerCommands.clear(); + compilerCommands.addAll(cppCompiler); + compilerCommands.addAll(cppFlags); + compilerCommands.addAll(headerDirs); + compilerCommands.add("@" + cppList.path()); + System.err.println("##### COMPILE #####"); + boolean flag = JProcess.startProcess(config.buildDir.file(), compilerCommands); + if(!flag) { + return false; + } } retFlag = true; diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java index 3094b1f4..a510c54a 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java @@ -107,6 +107,11 @@ protected boolean build(BuildConfig config) { androidCommand += ".cmd"; } + if(multiCoreCompile) { + int i = Runtime.getRuntime().availableProcessors(); + customArgs.add("-j" + i ); + } + CustomFileDescriptor childTarget = config.libDir.child("android"); ArrayList commands = new ArrayList<>(); commands.add(androidCommand); From 7f22b4a7ec253001b6bda86d3d503552d920bff8 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 30 Jul 2024 11:41:53 -0300 Subject: [PATCH 021/186] update emscripten target --- .../xpenatan/jparser/builder/targets/EmscriptenTarget.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java index eff7a299..ce71a1de 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java @@ -42,8 +42,7 @@ public EmscriptenTarget(IDLReader idlReader) { cppFlags.add("-c"); cppFlags.add("-std=c++17"); - cppFlags.add("-Os"); - cppFlags.add("-g0"); + cppFlags.add("-O3"); } @Override From 8534c9204e5e20a702a71bc290a47fdef92ff4f9 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 30 Jul 2024 14:10:50 -0300 Subject: [PATCH 022/186] Improve parser --- .../xpenatan/jparser/idl/IDLAttribute.java | 4 ++ .../xpenatan/jparser/idl/IDLReader.java | 43 +++++++++++++------ .../idl/parser/IDLAttributeParser.java | 4 +- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java index fde7de6e..5d0c3125 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java @@ -55,6 +55,10 @@ public void initAttribute(String line) { type = type.replace("long", "int"); } + if(type.contains("int int")) { + type = type.replace("int int", "long"); + } + if(type.contains("unsigned")) { type = type.replace("unsigned", "").trim(); } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java index 550a653e..8c73a510 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java @@ -139,11 +139,10 @@ private static void parseFile(IDLFile idlFile, ArrayList classLi int size = idlFile.lines.size(); for(int i = 0; i < size; i++) { String line = idlFile.lines.get(i).trim(); - String nextLine = ""; - if(i+1 < size) { - nextLine = idlFile.lines.get(i+1).trim(); - } - if(line.startsWith("//") || line.isEmpty()) { + line = removeComment(line); + String nextLine = getNextLine(idlFile.lines, i); + + if(line.isEmpty()) { if(foundStartClass || foundStartEnum) { String cmd = line.replace("//", "").trim(); if(cmd.startsWith("[-") && cmd.endsWith("]")) { @@ -189,13 +188,10 @@ private static void parseFile(IDLFile idlFile, ArrayList classLi classLines.add(line); } if(line.endsWith("};")) { - int nextLineIdx = i + 1; - if(nextLineIdx < size) { - String nextL = idlFile.lines.get(nextLineIdx); - if(nextL.contains(" implements ")) { - classLines.add(nextL.trim()); - i++; // add i so nextLine is not skipped on next loop - } + String nextL = getNextLine(idlFile.lines, i);; + if(nextL.contains(" implements ")) { + classLines.add(nextL.trim()); + i++; // add i so nextLine is not skipped on next loop } foundStartClass = false; IDLClass parserLineClass = new IDLClass(idlFile); @@ -208,4 +204,27 @@ private static void parseFile(IDLFile idlFile, ArrayList classLi } } } + + private static String removeComment(String line) { + int commentIndex = line.indexOf("//"); + if(commentIndex != -1) { + line = line.substring(0, commentIndex); + line = line.trim(); + } + return line; + } + + private static String getNextLine(ArrayList lines, int index) { + String nextLine = ""; + int size = lines.size(); + if(index + 1 < size) { + nextLine = lines.get(index+1).trim(); + nextLine = removeComment(nextLine); + if(nextLine.isEmpty() && index + 2 < size) { + nextLine = lines.get(index+2).trim(); + nextLine = removeComment(nextLine); + } + } + return nextLine; + } } \ No newline at end of file diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java index fd7f4e1b..25ab1992 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java @@ -42,8 +42,8 @@ public static void generateAttribute(IDLDefaultCodeParser idlParser, JParser jPa type = StaticJavaParser.parseType(attributeType); } catch(Exception e) { - e.printStackTrace(); - return; + System.err.println("Type error: " + attributeType); + throw e; } JParserItem parserUnitItem = jParser.getParserUnitItem(type.toString()); From bab38516baf53d0af7f5d5c375f7b655c7804965 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 30 Jul 2024 22:06:02 -0300 Subject: [PATCH 023/186] Smal cpp improvement --- .../xpenatan/jparser/cpp/CppCodeParser.java | 27 +++++++++++++---- .../xpenatan/jparser/idl/IDLAttribute.java | 15 ++++++---- .../xpenatan/jparser/idl/IDLHelper.java | 27 +++++++++++++++++ .../xpenatan/jparser/idl/IDLMethod.java | 30 ++----------------- .../xpenatan/jparser/idl/IDLReaderTest.java | 10 +++++++ 5 files changed, 70 insertions(+), 39 deletions(-) diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index 4f318d8e..088b5fdf 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -35,6 +35,8 @@ public class CppCodeParser extends IDLDefaultCodeParser { protected static final String TEMPLATE_TAG_ATTRIBUTE = "[ATTRIBUTE]"; protected static final String TEMPLATE_TAG_ENUM = "[ENUM]"; protected static final String TEMPLATE_TAG_ATTRIBUTE_TYPE = "[ATTRIBUTE_TYPE]"; + protected static final String TEMPLATE_TAG_RETURN_TYPE = "[RETURN_TYPE]"; + protected static final String TEMPLATE_TAG_CONST = "[CONST]"; protected static final String TEMPLATE_TAG_COPY_TYPE = "[COPY_TYPE]"; protected static final String TEMPLATE_TAG_COPY_PARAM = "[COPY_PARAM]"; protected static final String TEMPLATE_TAG_CONSTRUCTOR = "[CONSTRUCTOR]"; @@ -80,14 +82,15 @@ public class CppCodeParser extends IDLDefaultCodeParser { protected static final String ATTRIBUTE_GET_OBJECT_POINTER_TEMPLATE = "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + - "return (jlong)nativeObject->[ATTRIBUTE];\n"; + "[CONST][ATTRIBUTE_TYPE]* attr = nativeObject->[ATTRIBUTE];\n" + + "return (jlong)attr;\n"; protected static final String ATTRIBUTE_GET_PRIMITIVE_STATIC_TEMPLATE = "\nreturn [TYPE]::[ATTRIBUTE];\n"; protected static final String ATTRIBUTE_GET_PRIMITIVE_TEMPLATE = "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + - "return nativeObject->[ATTRIBUTE];\n"; + "return [CAST]nativeObject->[ATTRIBUTE];\n"; protected static final String METHOD_GET_OBJ_VALUE_TEMPLATE = "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + @@ -112,7 +115,8 @@ public class CppCodeParser extends IDLDefaultCodeParser { protected static final String METHOD_GET_OBJ_POINTER_TEMPLATE = "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + - "return (jlong)nativeObject->[METHOD];\n"; + "[CONST][RETURN_TYPE]* obj = nativeObject->[METHOD];\n" + + "return (jlong)obj;\n"; protected static final String METHOD_GET_REF_OBJ_POINTER_STATIC_TEMPLATE = "\nreturn (jlong)&[TYPE]::[METHOD];\n"; @@ -193,7 +197,12 @@ public void onIDLAttributeGenerated(JParser jParser, IDLAttribute idlAttribute, classTypeName = idlClass.classHeader.prefixName + classTypeName; } + String getPrimitiveCast = ""; String attributeType = idlAttribute.type; + String constTag = ""; + if(idlAttribute.isConst) { + constTag = "const "; + } IDLClass retTypeClass = idlAttribute.idlFile.getClass(attributeType); if(retTypeClass != null) { @@ -210,6 +219,7 @@ public void onIDLAttributeGenerated(JParser jParser, IDLAttribute idlAttribute, else { attributeReturnCast = "(" + idlEnum.typePrefix + "::" + attributeType + ")"; } + getPrimitiveCast = "(jint)"; } String content = null; @@ -246,7 +256,7 @@ public void onIDLAttributeGenerated(JParser jParser, IDLAttribute idlAttribute, .replace(TEMPLATE_TAG_TYPE, classTypeName); break; case GET_OBJECT_POINTER: - content = ATTRIBUTE_GET_OBJECT_POINTER_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName); + content = ATTRIBUTE_GET_OBJECT_POINTER_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_ATTRIBUTE_TYPE, attributeType).replace(TEMPLATE_TAG_CONST, constTag); break; case GET_OBJECT_POINTER_STATIC: content = ATTRIBUTE_GET_OBJECT_POINTER_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName); @@ -258,7 +268,7 @@ public void onIDLAttributeGenerated(JParser jParser, IDLAttribute idlAttribute, content = ATTRIBUTE_SET_PRIMITIVE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName); break; case GET_PRIMITIVE: - content = ATTRIBUTE_GET_PRIMITIVE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName); + content = ATTRIBUTE_GET_PRIMITIVE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_CAST, getPrimitiveCast); break; case GET_PRIMITIVE_STATIC: content = ATTRIBUTE_GET_PRIMITIVE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName); @@ -299,6 +309,11 @@ private void setupMethodGenerated(IDLMethod idlMethod, String param, ClassOrInte returnCastStr = "(jlong)"; } + String constTag = ""; + if(idlMethod.isReturnConst) { + constTag = "const "; + } + String operator = getOperation(idlMethod.operator, param); String content = null; IDLMethodOperation.Op op = IDLMethodOperation.getEnum(idlMethod, methodDeclaration, nativeMethod); @@ -352,7 +367,7 @@ private void setupMethodGenerated(IDLMethod idlMethod, String param, ClassOrInte content = METHOD_GET_OBJ_POINTER_STATIC_TEMPLATE.replace(TEMPLATE_TAG_METHOD, methodCaller).replace(TEMPLATE_TAG_TYPE, classTypeName); break; case GET_OBJ_POINTER: - content = METHOD_GET_OBJ_POINTER_TEMPLATE.replace(TEMPLATE_TAG_METHOD, methodCaller).replace(TEMPLATE_TAG_TYPE, classTypeName); + content = METHOD_GET_OBJ_POINTER_TEMPLATE.replace(TEMPLATE_TAG_METHOD, methodCaller).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_RETURN_TYPE, returnTypeStr).replace(TEMPLATE_TAG_CONST, constTag); break; case GET_PRIMITIVE_STATIC: content = METHOD_GET_PRIMITIVE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_METHOD, methodCaller).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_CAST, returnCastStr); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java index 5d0c3125..2dbe1dc8 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java @@ -34,17 +34,20 @@ public void initAttribute(String line) { if(leftSide.contains("static")) { isStatic = true; } - if(leftSide.contains("[Value]")) { - isValue = true; - } - if(leftSide.contains("[Const]")) { - isConst = true; + + String tagsStr = IDLHelper.getTags(leftSide); + if(!tagsStr.isEmpty()) { + if(tagsStr.contains("Value")) { + isValue = true; + } + if(leftSide.contains("Const")) { + isConst = true; + } } if(leftSide.contains("readonly")) { isReadOnly = true; } - if(type.contains("[]")) { isArray = true; type = type.replace("[]", "").trim(); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLHelper.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLHelper.java index 5d4ba290..805078e7 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLHelper.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLHelper.java @@ -43,4 +43,31 @@ public static String convertEnumToInt(IDLReader idlReader, String type) { } return type; } + + public static String getTags(String line) { + line = line.trim(); + int startIndex = line.indexOf("["); + int endIndex = -1; + if(startIndex != -1 && line.startsWith("[")) { + int count = 0; + for(int i = startIndex; i < line.length(); i++) { + char c = line.charAt(i); + if(c == '[') { + count++; + } + else if(c == ']') { + count--; + } + if(count == 0) { + endIndex = i; + break; + } + } + } + + if(startIndex != -1 && endIndex != -1) { + return line.substring(startIndex, endIndex + 1); + } + return ""; + } } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java index 40d192df..87968ce7 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java @@ -18,6 +18,7 @@ public class IDLMethod { public boolean isAny = false; public boolean isReturnRef; public boolean isReturnValue; + public boolean isReturnConst; public boolean isStaticMethod = false; public String operator = ""; @@ -34,10 +35,11 @@ public void initMethod(String line) { int index = line.indexOf("("); String leftSide = line.substring(0, index).trim(); - String tagsStr = getTags(leftSide); + String tagsStr = IDLHelper.getTags(leftSide); if(!tagsStr.isEmpty()) { isReturnRef = tagsStr.contains("Ref"); isReturnValue = tagsStr.contains("Value"); + isReturnConst = tagsStr.contains("Const"); leftSide = leftSide.replace(tagsStr, ""); tagsStr = tagsStr.substring(1, tagsStr.length()-1); @@ -115,32 +117,6 @@ public IDLMethod clone() { return cloned; } - private String getTags(String leftSide) { - int startIndex = leftSide.indexOf("["); - int endIndex = -1; - if(startIndex != -1 && leftSide.startsWith("[")) { - int count = 0; - for(int i = startIndex; i < leftSide.length(); i++) { - char c = leftSide.charAt(i); - if(c == '[') { - count++; - } - else if(c == ']') { - count--; - } - if(count == 0) { - endIndex = i; - break; - } - } - } - - if(startIndex != -1 && endIndex != -1) { - return leftSide.substring(startIndex, endIndex + 1); - } - return ""; - } - static String setParameters(IDLFile idlFile, String line, ArrayList out) { int firstIdx = line.indexOf("("); int lastIdx = line.indexOf(")"); diff --git a/jParser/idl/src/test/java/com/github/xpenatan/jparser/idl/IDLReaderTest.java b/jParser/idl/src/test/java/com/github/xpenatan/jparser/idl/IDLReaderTest.java index 95b98e68..36318e4b 100644 --- a/jParser/idl/src/test/java/com/github/xpenatan/jparser/idl/IDLReaderTest.java +++ b/jParser/idl/src/test/java/com/github/xpenatan/jparser/idl/IDLReaderTest.java @@ -10,6 +10,16 @@ public class IDLReaderTest { public static void setUp() throws Exception { } + @Test + public void test_getTag() { + String tag1 = "[Const, Value] readonly attribute Vec3 mDirection;"; + String tag2= "[Value] attribute SoftBodySharedSettingsSkinWeight[] mWeights;"; + String test1 = IDLHelper.getTags(tag1); + String test2 = IDLHelper.getTags(tag2); + Assert.assertEquals("[Const, Value]", test1); + Assert.assertEquals("[Value]", test2); + } + @Test public void test_NoDeleteClassTest_not_null() { IDLReader idlReader = IDLReader.readIDL("src\\test\\resources\\idl\\Test.idl"); From 1044dab4946864bc33c32d6cf4296dc47e5285d6 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 4 Aug 2024 11:46:14 -0300 Subject: [PATCH 024/186] Update build structure --- .../github/xpenatan/jparser/builder/BuildTarget.java | 2 +- .../xpenatan/jparser/builder/DefaultBuildTarget.java | 11 +++++++---- .../com/github/xpenatan/jparser/builder/JBuilder.java | 2 +- .../jparser/builder/targets/AndroidTarget.java | 3 +-- .../jparser/builder/targets/EmscriptenLibTarget.java | 11 ++--------- .../jparser/builder/targets/EmscriptenTarget.java | 10 ++-------- 6 files changed, 14 insertions(+), 25 deletions(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/BuildTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/BuildTarget.java index 60cd94c6..9acf3790 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/BuildTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/BuildTarget.java @@ -16,5 +16,5 @@ public static boolean isUnix() { return (OS.contains("nix") || OS.contains("nux") || OS.contains("aix") || OS.contains("Linux")); } - protected abstract boolean build(BuildConfig config); + protected abstract boolean buildInternal(BuildConfig config); } \ No newline at end of file diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java index 4536f414..71eb5cb8 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java @@ -46,17 +46,20 @@ protected DefaultBuildTarget() { linkerCompiler.add("x86_64-w64-mingw32-g++"); } - protected void setup(BuildConfig config) {} - - protected boolean build(BuildConfig config) { + @Override + protected boolean buildInternal(BuildConfig config) { CustomFileDescriptor childTarget = config.buildDir.child(tempBuildDir); if(childTarget.exists()) { childTarget.deleteDirectory(); } childTarget.mkdirs(); - setup(config); + return build(config, childTarget); + } + + protected void setup(BuildConfig config) {} + protected boolean build(BuildConfig config, CustomFileDescriptor childTarget) { ArrayList cppFiles = new ArrayList<>(getCPPFiles(config.sourceDir, cppInclude, cppExclude, filterCPPSuffix)); for(CustomFileDescriptor sourceDir : config.additionalSourceDirs) { ArrayList cppFiles1 = getCPPFiles(sourceDir, cppInclude, cppExclude, filterCPPSuffix); diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/JBuilder.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/JBuilder.java index 156013e7..c00f228a 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/JBuilder.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/JBuilder.java @@ -17,7 +17,7 @@ public static void build(BuildConfig config, BuildMultiTarget ... targets) { for(BuildTarget buildTarget : target.multiTarget) { String targetName = buildTarget.getClass().getSimpleName(); System.err.println("##### Building: " + targetName + " #####"); - if(!buildTarget.build(config)) { + if(!buildTarget.buildInternal(config)) { throw new RuntimeException(); } } diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java index a510c54a..d21fcbc0 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java @@ -31,7 +31,7 @@ public AndroidTarget() { } @Override - protected boolean build(BuildConfig config) { + protected boolean build(BuildConfig config, CustomFileDescriptor childTarget) { CustomFileDescriptor androidDir = config.buildDir; if(!androidDir.exists()) { androidDir.mkdirs(); @@ -112,7 +112,6 @@ protected boolean build(BuildConfig config) { customArgs.add("-j" + i ); } - CustomFileDescriptor childTarget = config.libDir.child("android"); ArrayList commands = new ArrayList<>(); commands.add(androidCommand); commands.addAll(customArgs); diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenLibTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenLibTarget.java index e1b7f5d7..c7cb642d 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenLibTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenLibTarget.java @@ -4,7 +4,6 @@ import com.github.xpenatan.jparser.builder.DefaultBuildTarget; import com.github.xpenatan.jparser.core.util.CustomFileDescriptor; import java.io.File; -import static com.github.xpenatan.jparser.builder.BuildTarget.isWindows; // Test Target @Deprecated @@ -55,13 +54,7 @@ public EmscriptenLibTarget() { } @Override - protected boolean build(BuildConfig config) { - CustomFileDescriptor childTarget = config.buildDir.child(tempBuildDir); - if(childTarget.exists()) { - childTarget.delete(); - } - childTarget.mkdirs(); - + protected boolean build(BuildConfig config, CustomFileDescriptor childTarget) { CustomFileDescriptor jsglueDir = config.sourceDir.child("jsglue"); if(!jsglueDir.exists()) { jsglueDir.mkdirs(); @@ -88,6 +81,6 @@ protected boolean build(BuildConfig config) { linkerFlags.add("-s"); linkerFlags.add("EXPORT_NAME='" + libName + "'"); cppFlags.add("-c"); - return super.build(config); + return super.build(config, childTarget); } } diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java index ce71a1de..2fc22cb6 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java @@ -46,18 +46,12 @@ public EmscriptenTarget(IDLReader idlReader) { } @Override - protected boolean build(BuildConfig config) { + protected boolean build(BuildConfig config, CustomFileDescriptor childTarget) { String libName = this.libName; if(libName.isEmpty()) { libName = config.libName; } - CustomFileDescriptor childTarget = config.buildDir.child(tempBuildDir); - if(childTarget.exists()) { - childTarget.delete(); - } - childTarget.mkdirs(); - CustomFileDescriptor jsglueDir = config.sourceDir.child("jsglue"); if(!jsglueDir.exists()) { jsglueDir.mkdirs(); @@ -119,7 +113,7 @@ protected boolean build(BuildConfig config) { linkerFlags.add("EXPORT_NAME='" + libName + "'"); } - return super.build(config); + return super.build(config, childTarget); } @Override From 7021f0461a4590ff7e9c352e647d789f00eb7211 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 4 Aug 2024 12:09:26 -0300 Subject: [PATCH 025/186] Move helper h file to a separated folder --- .../jparser/builder/DefaultBuildTarget.java | 17 ++++++++++++++++- .../jparser/builder/targets/AndroidTarget.java | 2 +- .../builder/targets/EmscriptenTarget.java | 10 +--------- .../jparser/cpp/NativeCPPGenerator.java | 7 ------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java index 71eb5cb8..577a8b80 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java @@ -11,6 +11,8 @@ public abstract class DefaultBuildTarget extends BuildTarget { + private static String helperName = "IDLHelper.h"; + public boolean multiCoreCompile = true; public String tempBuildDir; @@ -38,9 +40,11 @@ public abstract class DefaultBuildTarget extends BuildTarget { public boolean shouldCompile = true; public boolean shouldLink = true; - public boolean isStatic = false; + protected CustomFileDescriptor idlDir; + protected CustomFileDescriptor idlHelperHFile; + protected DefaultBuildTarget() { cppCompiler.add("x86_64-w64-mingw32-g++"); linkerCompiler.add("x86_64-w64-mingw32-g++"); @@ -53,6 +57,17 @@ protected boolean buildInternal(BuildConfig config) { childTarget.deleteDirectory(); } childTarget.mkdirs(); + + idlDir = config.sourceDir.child("idl"); + if(!idlDir.exists()) { + idlDir.mkdirs(); + } + + CustomFileDescriptor idlHelperCPP = new CustomFileDescriptor(helperName, CustomFileDescriptor.FileType.Classpath); + idlHelperCPP.copyTo(idlDir, false); + idlHelperHFile = idlDir.child(idlHelperCPP.name()); + headerDirs.add("-I" + idlDir.path()); + setup(config); return build(config, childTarget); } diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java index d21fcbc0..584cf2ca 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java @@ -26,7 +26,6 @@ public AndroidTarget() { linkerFlags.add("-lm"); cppInclude.add("**/jniglue/JNIGlue.cpp"); - headerDirs.add("jni-headers/"); headerDirs.add("jni-headers/linux"); } @@ -49,6 +48,7 @@ protected boolean build(BuildConfig config, CustomFileDescriptor childTarget) { String headerDirsStr = ""; for(String headerDir : headerDirs) { + headerDir = headerDir.replace("-I", ""); headerDirsStr += headerDir + " "; } headerDirsStr = headerDirsStr.trim(); diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java index 2fc22cb6..77154de9 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java @@ -59,7 +59,7 @@ protected boolean build(BuildConfig config, CustomFileDescriptor childTarget) { if(compileGlueCode && !isStatic) { cppInclude.add("**/jsglue/*.cpp"); - copyHelperClass(jsglueDir); + headerDirs.add("-include" + idlHelperHFile.path()); } if(idlReader != null) { @@ -152,14 +152,6 @@ private boolean createGlueCode(CustomFileDescriptor mergedIDLFile, CustomFileDes return JProcess.startProcess(jsglueDir.file(), generateGlueCommand); } - private void copyHelperClass(CustomFileDescriptor jsglueDir) { - // Copy IDLHelper from base module. - CustomFileDescriptor idlHelperCPP = new CustomFileDescriptor("IDLHelper.h", CustomFileDescriptor.FileType.Classpath); - idlHelperCPP.copyTo(jsglueDir, false); - CustomFileDescriptor cppFile = jsglueDir.child(idlHelperCPP.name()); - headerDirs.add("-include" + cppFile.path()); - } - private CustomFileDescriptor mergeIDLFile(CustomFileDescriptor jsglueDir) { String idlStr = idlReader.mergeIDLFiles(); CustomFileDescriptor mergedIdlFile = jsglueDir.child("IDLMerged.idl"); diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/NativeCPPGenerator.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/NativeCPPGenerator.java index 5c3c3d5c..864a7162 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/NativeCPPGenerator.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/NativeCPPGenerator.java @@ -262,13 +262,6 @@ public void generate(JParser jParser) { String gluePathStr = cppDestinationDir + File.separator + ".." + File.separator + "jniglue" + File.separator; CustomFileDescriptor gluePath = new CustomFileDescriptor(gluePathStr); - if(JParser.CREATE_IDL_HELPER) { - // Create cpp file if flag is enable - InputStream idlHelperClass = getClass().getClassLoader().getResourceAsStream(helperName); - CustomFileDescriptor helperFile = gluePath.child(helperName); - helperFile.write(idlHelperClass, false); - } - String cppGlueHPath = gluePathStr + cppGlueName + ".h"; String cppGluePath = gluePathStr + cppGlueName + ".cpp"; CustomFileDescriptor fileDescriptor = new CustomFileDescriptor(cppGlueHPath); From 171b0a36e51c22049bbbf6d6919f7a8984258a1f Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 4 Aug 2024 12:17:05 -0300 Subject: [PATCH 026/186] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ec972f1f..c4c4a59a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ jParser is a small Java library that helps bind C/C++ code to desktop, mobile, a It was inspired by [gdx-jnigen](https://github.com/libgdx/gdx-jnigen) that you add a native code into a code block. This code block will be translated to the specific code target. You can add multiple code block targets in the same java source. For each code target, it will generate a new java source code. -For the web, it needs emscripten to generate a js/wasm file and teaVM for the binding part. +For the web, it needs emscripten and a webidl file to generate a js/wasm file and [teavm](https://github.com/konsoletyper/teavm). The generated classes in teavm module use JSBody to communicate with javascript. jParser only supports ```JNI``` and ```TEAVM``` code targets. From 09cd88eea6318c3340af58a62002c070b3cfe036 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 4 Aug 2024 12:18:23 -0300 Subject: [PATCH 027/186] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c4c4a59a..a4c2ab6f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ jParser is a small Java library that helps bind C/C++ code to desktop, mobile, a It was inspired by [gdx-jnigen](https://github.com/libgdx/gdx-jnigen) that you add a native code into a code block. This code block will be translated to the specific code target. You can add multiple code block targets in the same java source. For each code target, it will generate a new java source code. -For the web, it needs emscripten and a webidl file to generate a js/wasm file and [teavm](https://github.com/konsoletyper/teavm). The generated classes in teavm module use JSBody to communicate with javascript. +For the web, it needs emscripten to generate a js/wasm file and [teavm](https://github.com/konsoletyper/teavm). The generated classes in teavm module use JSBody to communicate with javascript. jParser only supports ```JNI``` and ```TEAVM``` code targets. From 92ae9f4c6bf0bf8280aa06b950441a05e42010b8 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 4 Aug 2024 12:31:44 -0300 Subject: [PATCH 028/186] Fix lib target --- .../github/xpenatan/jparser/builder/targets/AndroidTarget.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java index 584cf2ca..88ecfe30 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java @@ -112,12 +112,13 @@ protected boolean build(BuildConfig config, CustomFileDescriptor childTarget) { customArgs.add("-j" + i ); } + CustomFileDescriptor libTarget = config.libDir.child("android"); ArrayList commands = new ArrayList<>(); commands.add(androidCommand); commands.addAll(customArgs); commands.add("NDK_PROJECT_PATH=."); commands.add("NDK_APPLICATION_MK=Application.mk"); - commands.add(" NDK_LIBS_OUT=" + childTarget.path()); + commands.add(" NDK_LIBS_OUT=" + libTarget.path()); if(!JProcess.startProcess(androidDir.file(), commands)) { return false; } From 82ebe558803b3a25efbf1e940275df131d056d9f Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 4 Aug 2024 12:32:59 -0300 Subject: [PATCH 029/186] Rename param --- .../jparser/builder/DefaultBuildTarget.java | 16 ++++++++-------- .../jparser/builder/targets/AndroidTarget.java | 2 +- .../builder/targets/EmscriptenLibTarget.java | 4 ++-- .../builder/targets/EmscriptenTarget.java | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java index 577a8b80..49923e5e 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java @@ -74,28 +74,28 @@ protected boolean buildInternal(BuildConfig config) { protected void setup(BuildConfig config) {} - protected boolean build(BuildConfig config, CustomFileDescriptor childTarget) { + protected boolean build(BuildConfig config, CustomFileDescriptor buildTargetTemp) { ArrayList cppFiles = new ArrayList<>(getCPPFiles(config.sourceDir, cppInclude, cppExclude, filterCPPSuffix)); for(CustomFileDescriptor sourceDir : config.additionalSourceDirs) { ArrayList cppFiles1 = getCPPFiles(sourceDir, cppInclude, cppExclude, filterCPPSuffix); cppFiles.addAll(cppFiles1); } - if(shouldCompile && shouldLink && compile(config, childTarget, cppFiles)) { - return link(config, childTarget); + if(shouldCompile && shouldLink && compile(config, buildTargetTemp, cppFiles)) { + return link(config, buildTargetTemp); } else if(shouldCompile && !shouldLink) { - return compile(config, childTarget, cppFiles); + return compile(config, buildTargetTemp, cppFiles); } else if(!shouldCompile && shouldLink) { - return link(config, childTarget); + return link(config, buildTargetTemp); } else { return false; } } - private boolean compile(BuildConfig config, CustomFileDescriptor childTarget, ArrayList cppFiles) { + private boolean compile(BuildConfig config, CustomFileDescriptor buildTargetTemp, ArrayList cppFiles) { boolean retFlag = false; String compiledPaths = ""; @@ -103,7 +103,7 @@ private boolean compile(BuildConfig config, CustomFileDescriptor childTarget, Ar String path = file.path(); compiledPaths = compiledPaths + "\n" + path; } - CustomFileDescriptor cppList = childTarget.child("cpp.txt"); + CustomFileDescriptor cppList = buildTargetTemp.child("cpp.txt"); cppList.writeString(compiledPaths.trim(), false); if(multiCoreCompile) { @@ -159,7 +159,7 @@ private boolean compile(BuildConfig config, CustomFileDescriptor childTarget, Ar ArrayList files = new ArrayList<>(); getObjectFiles(config.buildDir, files); for(CustomFileDescriptor file : files) { - file.moveTo(childTarget); + file.moveTo(buildTargetTemp); } return retFlag; } diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java index 88ecfe30..af92f6a8 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java @@ -30,7 +30,7 @@ public AndroidTarget() { } @Override - protected boolean build(BuildConfig config, CustomFileDescriptor childTarget) { + protected boolean build(BuildConfig config, CustomFileDescriptor buildTargetTemp) { CustomFileDescriptor androidDir = config.buildDir; if(!androidDir.exists()) { androidDir.mkdirs(); diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenLibTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenLibTarget.java index c7cb642d..d7c6e159 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenLibTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenLibTarget.java @@ -54,7 +54,7 @@ public EmscriptenLibTarget() { } @Override - protected boolean build(BuildConfig config, CustomFileDescriptor childTarget) { + protected boolean build(BuildConfig config, CustomFileDescriptor buildTargetTemp) { CustomFileDescriptor jsglueDir = config.sourceDir.child("jsglue"); if(!jsglueDir.exists()) { jsglueDir.mkdirs(); @@ -81,6 +81,6 @@ protected boolean build(BuildConfig config, CustomFileDescriptor childTarget) { linkerFlags.add("-s"); linkerFlags.add("EXPORT_NAME='" + libName + "'"); cppFlags.add("-c"); - return super.build(config, childTarget); + return super.build(config, buildTargetTemp); } } diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java index 77154de9..dca29e0e 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java @@ -46,7 +46,7 @@ public EmscriptenTarget(IDLReader idlReader) { } @Override - protected boolean build(BuildConfig config, CustomFileDescriptor childTarget) { + protected boolean build(BuildConfig config, CustomFileDescriptor buildTargetTemp) { String libName = this.libName; if(libName.isEmpty()) { libName = config.libName; @@ -113,7 +113,7 @@ protected boolean build(BuildConfig config, CustomFileDescriptor childTarget) { linkerFlags.add("EXPORT_NAME='" + libName + "'"); } - return super.build(config, childTarget); + return super.build(config, buildTargetTemp); } @Override From 81174a56c9ef36f1a456355fdc2fe1f19b4c0245 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 4 Aug 2024 21:06:45 -0300 Subject: [PATCH 030/186] Remove unused code --- .../jparser/teavm/TeaVMCodeParser.java | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index a38989e7..0ac8b944 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -515,37 +515,6 @@ public void onParserComplete(JParser jParser, ArrayList parserItems for(int i = 0; i < parserItems.size(); i++) { JParserItem parserItem = parserItems.get(i); CompilationUnit unit = parserItem.unit; - for(ImportDeclaration anImport : unit.getImports()) { - Name name = anImport.getName(); - String importPath = ""; - Optional qualifier = name.getQualifier(); - if(qualifier.isPresent()) { - importPath = qualifier.get().asString(); - } - String identifier = name.getIdentifier(); - - boolean skipUnit = false; - if(!JParser.CREATE_IDL_HELPER) { - // Hack to skip the generated lib and use the main one - ArrayList baseIDLClasses = getBaseIDLClasses(); - for(String baseIDLClass : baseIDLClasses) { - String[] split = baseIDLClass.split("\\."); - String s = split[split.length - 1]; - if(s.equals(identifier)) { - skipUnit = true; - break; - } - } - } - if(!skipUnit) { - JParserItem parserUnitItem = jParser.getParserUnitItem(prefix + identifier); - if(parserUnitItem != null) { - String newImport = packagePrefix + importPath + "."; - anImport.setName(newImport + prefix + identifier); - } - } - } - PackageDeclaration packageDeclaration = unit.getPackageDeclaration().get(); String nameAsString1 = packageDeclaration.getNameAsString(); packageDeclaration.setName(packagePrefix + nameAsString1); From ff338686833fb4ff1bec80669a9b26fe7e544065 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 4 Aug 2024 23:06:41 -0300 Subject: [PATCH 031/186] Remove loader --- jParser/loader/loader-teavm/build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/jParser/loader/loader-teavm/build.gradle.kts b/jParser/loader/loader-teavm/build.gradle.kts index ef864dc9..ece835f9 100644 --- a/jParser/loader/loader-teavm/build.gradle.kts +++ b/jParser/loader/loader-teavm/build.gradle.kts @@ -5,7 +5,6 @@ plugins { val moduleName = "loader-teavm" dependencies { - api("com.badlogicgames.gdx:gdx-jnigen-loader:${LibExt.jniGenVersion}") implementation(project(":jParser:loader:loader-core")) implementation("com.github.xpenatan.gdx-teavm:asset-loader:${LibExt.gdxTeaVMVersion}") } From f70381b39a799c0d3a24a389a0b3e09d28d0027a Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 5 Aug 2024 20:41:23 -0300 Subject: [PATCH 032/186] update mac version --- .../github/xpenatan/jparser/builder/targets/MacTarget.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java index 4a1460b5..cf4b2f10 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java @@ -11,12 +11,14 @@ public class MacTarget extends DefaultBuildTarget { private final String macMinTarget; + public static String MIN_MAC_VERSION = "10.13"; + public MacTarget() { this(false); } public MacTarget(boolean isArm) { - this(isArm, "10.12"); + this(isArm, MIN_MAC_VERSION); } public MacTarget(boolean isArm, String macMinTarget) { From e7b250c3931868f4d10b4f82cc438d977dcb552a Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 5 Aug 2024 20:43:30 -0300 Subject: [PATCH 033/186] update mac version --- .../com/github/xpenatan/jparser/builder/targets/MacTarget.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java index cf4b2f10..f39de0d9 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java @@ -11,7 +11,7 @@ public class MacTarget extends DefaultBuildTarget { private final String macMinTarget; - public static String MIN_MAC_VERSION = "10.13"; + public static String MIN_MAC_VERSION = "13.0"; public MacTarget() { this(false); From a4eb312713fd99ffde1e7c3a2c3581796f42ec26 Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 5 Aug 2024 20:45:10 -0300 Subject: [PATCH 034/186] update mac version --- .../com/github/xpenatan/jparser/builder/targets/MacTarget.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java index f39de0d9..cf4b2f10 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/MacTarget.java @@ -11,7 +11,7 @@ public class MacTarget extends DefaultBuildTarget { private final String macMinTarget; - public static String MIN_MAC_VERSION = "13.0"; + public static String MIN_MAC_VERSION = "10.13"; public MacTarget() { this(false); From d1cc9d98915b1feac771eef53a38cb70bb81bde4 Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 5 Aug 2024 21:28:54 -0300 Subject: [PATCH 035/186] Fix/Revert renaming teavm package --- .../idl/parser/IDLClassGeneratorParser.java | 1 + .../jparser/teavm/TeaVMCodeParser.java | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java index 4efae3c4..560cf4bc 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java @@ -308,6 +308,7 @@ public void onParserComplete(JParser jParser, ArrayList parserItems boolean skipUnit = false; if(!JParser.CREATE_IDL_HELPER) { + //TODO implement better class renaming // Hack to look for idl classes that was generated with the main lib ArrayList baseIDLClasses = getBaseIDLClasses(); for(String baseIDLClass : baseIDLClasses) { diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index 0ac8b944..d5a12d2d 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -515,6 +515,38 @@ public void onParserComplete(JParser jParser, ArrayList parserItems for(int i = 0; i < parserItems.size(); i++) { JParserItem parserItem = parserItems.get(i); CompilationUnit unit = parserItem.unit; + for(ImportDeclaration anImport : unit.getImports()) { + Name name = anImport.getName(); + String importPath = ""; + Optional qualifier = name.getQualifier(); + if(qualifier.isPresent()) { + importPath = qualifier.get().asString(); + } + String identifier = name.getIdentifier(); + + boolean skipUnit = false; + if(!JParser.CREATE_IDL_HELPER) { + //TODO implement better class renaming + // Hack to skip the generated lib and use the main one + ArrayList baseIDLClasses = getBaseIDLClasses(); + for(String baseIDLClass : baseIDLClasses) { + String[] split = baseIDLClass.split("\\."); + String s = split[split.length - 1]; + if(s.equals(identifier)) { + skipUnit = true; + break; + } + } + } + if(!skipUnit) { + JParserItem parserUnitItem = jParser.getParserUnitItem(prefix + identifier); + if(parserUnitItem != null) { + String newImport = packagePrefix + importPath + "."; + anImport.setName(newImport + prefix + identifier); + } + } + } + PackageDeclaration packageDeclaration = unit.getPackageDeclaration().get(); String nameAsString1 = packageDeclaration.getNameAsString(); packageDeclaration.setName(packagePrefix + nameAsString1); From 134d7a21d48341ab7b46070699d433db990cce88 Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 7 Aug 2024 07:25:57 -0300 Subject: [PATCH 036/186] Force stop building when something fails --- .../jparser/builder/DefaultBuildTarget.java | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java index 49923e5e..bc4d66b9 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java @@ -117,29 +117,40 @@ private boolean compile(BuildConfig config, CustomFileDescriptor buildTargetTemp String path = file.path(); Future submit = executorService.submit(() -> { - ArrayList threadCommands = new ArrayList<>(); - threadCommands.addAll(cppCompiler); - threadCommands.addAll(cppFlags); - threadCommands.addAll(headerDirs); - threadCommands.add(path); - boolean flag = JProcess.startProcess(config.buildDir.file(), threadCommands); - if(!flag) { - throw new RuntimeException("Compile Error"); + if(multiCoreCompile) { + ArrayList threadCommands = new ArrayList<>(); + threadCommands.addAll(cppCompiler); + threadCommands.addAll(cppFlags); + threadCommands.addAll(headerDirs); + threadCommands.add(path); + boolean flag = JProcess.startProcess(config.buildDir.file(), threadCommands); + if(!flag) { + multiCoreCompile = false; + throw new RuntimeException("Compile Error"); + } } }); futures.add(submit); } for (Future future : futures) { - try { - future.get(); - } catch (Exception e) { - e.printStackTrace(); - executorService.shutdown(); - return false; + if(multiCoreCompile) { + try { + future.get(); + } catch (Exception e) { + e.printStackTrace(); + multiCoreCompile = false; + break; + } + } + else { + break; } } executorService.shutdown(); + if(!multiCoreCompile) { + return false; + } } else { compilerCommands.clear(); From d07e8f16308169c297022f1f6300ac4689c2e7dd Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 7 Aug 2024 08:13:26 -0300 Subject: [PATCH 037/186] Revert back method attributes using get_ and set_ --- .../xpenatan/jparser/example/app/AppTest.java | 36 +++++++++---------- .../idl/parser/IDLAttributeParser.java | 8 ++--- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java index 9ccea2ac..a83cc0b7 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java @@ -88,7 +88,7 @@ private void initLib() { System.out.println("EnumInNamespace e_namespace_val: " + EnumInNamespace.e_namespace_val); ReturnClass returnValueObject = normalClass.getReturnValueObject(); - System.out.println("returnValueObject: " + returnValueObject.value()); + System.out.println("returnValueObject: " + returnValueObject.get_value()); normalClass.printText(10, "printText HELLO"); IDLFloat floatArray = IDLFloat.TMP_1; @@ -101,12 +101,12 @@ private void initLib() { System.out.println("NormalClass.subIntValue: " + NormalClass.subIntValue(2, 1)); OperatorClass operatorClass1 = new OperatorClass(); - operatorClass1.value(41); + operatorClass1.set_value(41); OperatorClass operatorClass2 = new OperatorClass(); - operatorClass2.value(3); + operatorClass2.set_value(3); operatorClass1.copy(operatorClass2); - System.out.println("operatorClass1 copy: " + operatorClass1.value()); + System.out.println("operatorClass1 copy: " + operatorClass1.get_value()); testPrimitive(); @@ -116,35 +116,35 @@ private void initLib() { private void testPrimitive() { System.out.println("########## TESTING ATTRIBUTES ##########"); - NormalClass.hiddenInt_static(22); - int hiddenIntStatic = NormalClass.hiddenInt_static(); + NormalClass.set_hiddenInt_static(22); + int hiddenIntStatic = NormalClass.get_hiddenInt_static(); System.out.println("hiddenIntStatic: " + hiddenIntStatic); - ReturnClass nullPointerReturnClassStatic = NormalClass.nullPointerReturnClass_static(); + ReturnClass nullPointerReturnClassStatic = NormalClass.get_nullPointerReturnClass_static(); System.out.println("nullPointerReturnClassStatic: " + nullPointerReturnClassStatic); // ReturnClass pointerReturnClassStatic = NormalClass.get_pointerReturnClass_static(); // pointerReturnClassStatic.set_value(51); // System.out.println("pointerReturnClassStatic: " + pointerReturnClassStatic.get_value()); - ReturnClass valueReturnClassStatic = NormalClass.valueReturnClass_static(); - System.out.println("valueReturnClassStatic: " + valueReturnClassStatic.value()); + ReturnClass valueReturnClassStatic = NormalClass.get_valueReturnClass_static(); + System.out.println("valueReturnClassStatic: " + valueReturnClassStatic.get_value()); NormalClass normalClass = new NormalClass(); - normalClass.hiddenInt(4); - int hiddenInt = normalClass.hiddenInt(); + normalClass.set_hiddenInt(4); + int hiddenInt = normalClass.get_hiddenInt(); System.out.println("hiddenInt: " + hiddenInt); - ReturnClass pointerReturnClass = normalClass.pointerReturnClass(); - pointerReturnClass.value(11); - System.out.println("pointerReturnClass: " + pointerReturnClass.value()); + ReturnClass pointerReturnClass = normalClass.get_pointerReturnClass(); + pointerReturnClass.set_value(11); + System.out.println("pointerReturnClass: " + pointerReturnClass.get_value()); - ReturnClass valueReturnClass = normalClass.valueReturnClass(); - valueReturnClass.value(12); - System.out.println("valueReturnClass: " + valueReturnClass.value()); + ReturnClass valueReturnClass = normalClass.get_valueReturnClass(); + valueReturnClass.set_value(12); + System.out.println("valueReturnClass: " + valueReturnClass.get_value()); - ReturnClass nullPointerReturnClass = normalClass.nullPointerReturnClass(); + ReturnClass nullPointerReturnClass = normalClass.get_nullPointerReturnClass(); System.out.println("nullPointerReturnClass: " + nullPointerReturnClass); } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java index 25ab1992..09976a52 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java @@ -94,7 +94,7 @@ public static void generateAttribute(IDLDefaultCodeParser idlParser, JParser jPa if(getMethodDeclaration != null) { getMethodDeclaration.remove(); } - String getMethodName = attributeName; + String getMethodName = ATTRIBUTE_PREFIX_GET + attributeName; getMethodDeclaration = classOrInterfaceDeclaration.addMethod(getMethodName, Modifier.Keyword.PUBLIC); getMethodDeclaration.setStatic(idlAttribute.isStatic); getMethodDeclaration.setType(type); @@ -102,7 +102,7 @@ public static void generateAttribute(IDLDefaultCodeParser idlParser, JParser jPa IDLDefaultCodeParser.setDefaultReturnValues(jParser, unit, type, getMethodDeclaration); if(idlParser.generateClass) { - setupAttributeMethod(idlParser, jParser, idlAttribute, false, classOrInterfaceDeclaration, getMethodDeclaration, ATTRIBUTE_PREFIX_GET + getMethodName); + setupAttributeMethod(idlParser, jParser, idlAttribute, false, classOrInterfaceDeclaration, getMethodDeclaration, getMethodName); } } @@ -114,7 +114,7 @@ public static void generateAttribute(IDLDefaultCodeParser idlParser, JParser jPa if(setMethodDeclaration != null) { setMethodDeclaration.remove(); } - String setMethodName = attributeName; + String setMethodName = ATTRIBUTE_PREFIX_SET + attributeName; setMethodDeclaration = classOrInterfaceDeclaration.addMethod(setMethodName, Modifier.Keyword.PUBLIC); setMethodDeclaration.setStatic(idlAttribute.isStatic); Parameter parameter = setMethodDeclaration.addAndGetParameter(type, attributeName); @@ -122,7 +122,7 @@ public static void generateAttribute(IDLDefaultCodeParser idlParser, JParser jPa JParserHelper.addMissingImportType(jParser, unit, paramType); if(idlParser.generateClass) { - setupAttributeMethod(idlParser, jParser, idlAttribute, true, classOrInterfaceDeclaration, setMethodDeclaration, ATTRIBUTE_PREFIX_SET + setMethodName); + setupAttributeMethod(idlParser, jParser, idlAttribute, true, classOrInterfaceDeclaration, setMethodDeclaration, setMethodName); } } } From 026faa69a9b18553bee76b7b3886c084e523c6c9 Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 7 Aug 2024 08:39:13 -0300 Subject: [PATCH 038/186] update readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index a4c2ab6f..2784cdda 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,9 @@ jParser has two part. To improve even more the long hours of porting each method manually, jParser also has Emscripten WebIDL support. You create a webidl file, and it will generate binding code for JNI and teaVM. It's not 100%, but it will reduce the amount of work binding big libraries. You can check the example:lib module or gdx-imgui for a complete example. +It will create the exact same method as the webidl file. If C++ is Pascal case like in ImGui, then Java methods will also be Pascal case.
+C/C++ attributes are converted to methods, it starts with 'set_' or 'get_'. + Libraries usisng jParser:
- [gdx-imgui](https://github.com/xpenatan/gdx-imgui) - [gdx-lua](https://github.com/xpenatan/gdx-lua) From 6158965eb0bb9eb35dd18e4270c7fbd96c15fcce Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 7 Aug 2024 08:55:24 -0300 Subject: [PATCH 039/186] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2784cdda..52a48ddc 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ jParser has two part. To improve even more the long hours of porting each method manually, jParser also has Emscripten WebIDL support. You create a webidl file, and it will generate binding code for JNI and teaVM. It's not 100%, but it will reduce the amount of work binding big libraries. You can check the example:lib module or gdx-imgui for a complete example. -It will create the exact same method as the webidl file. If C++ is Pascal case like in ImGui, then Java methods will also be Pascal case.
+It will create the exact same method as the webidl file. If C++ is case-sensitive as in ImGui, the Java methods will be also case-sensitive.
C/C++ attributes are converted to methods, it starts with 'set_' or 'get_'. Libraries usisng jParser:
From 0ba64a64b190fa01cb807a947dfc21bd614e26ce Mon Sep 17 00:00:00 2001 From: Natan Date: Fri, 9 Aug 2024 20:21:35 -0300 Subject: [PATCH 040/186] Add lib-test --- .gitignore | 2 + build.gradle.kts | 6 +- example/lib-test/lib-android/build.gradle.kts | 31 +++ example/lib-test/lib-base/build.gradle.kts | 10 + .../java/lib/emscripten/TestLibLoader.java | 42 +++ example/lib-test/lib-build/build.gradle.kts | 98 +++++++ .../src/main/cpp/custom/CustomCode.cpp | 1 + .../src/main/cpp/custom/CustomCode.h | 4 + .../src/main/cpp/source/test/src/test.cpp | 15 ++ .../src/main/cpp/source/test/src/test.h | 243 ++++++++++++++++++ .../lib-test/lib-build/src/main/cpp/test.idl | 212 +++++++++++++++ .../lib-build/src/main/java/BuildLib.java | 187 ++++++++++++++ example/lib-test/lib-core/build.gradle.kts | 19 ++ example/lib-test/lib-desktop/build.gradle.kts | 34 +++ example/lib-test/lib-teavm/build.gradle.kts | 35 +++ .../resources/META-INF/gdx-teavm.properties | 0 .../main/resources/META-INF/teavm.properties | 1 + settings.gradle.kts | 7 + 18 files changed, 946 insertions(+), 1 deletion(-) create mode 100644 example/lib-test/lib-android/build.gradle.kts create mode 100644 example/lib-test/lib-base/build.gradle.kts create mode 100644 example/lib-test/lib-base/src/main/java/lib/emscripten/TestLibLoader.java create mode 100644 example/lib-test/lib-build/build.gradle.kts create mode 100644 example/lib-test/lib-build/src/main/cpp/custom/CustomCode.cpp create mode 100644 example/lib-test/lib-build/src/main/cpp/custom/CustomCode.h create mode 100644 example/lib-test/lib-build/src/main/cpp/source/test/src/test.cpp create mode 100644 example/lib-test/lib-build/src/main/cpp/source/test/src/test.h create mode 100644 example/lib-test/lib-build/src/main/cpp/test.idl create mode 100644 example/lib-test/lib-build/src/main/java/BuildLib.java create mode 100644 example/lib-test/lib-core/build.gradle.kts create mode 100644 example/lib-test/lib-desktop/build.gradle.kts create mode 100644 example/lib-test/lib-teavm/build.gradle.kts create mode 100644 example/lib-test/lib-teavm/src/main/resources/META-INF/gdx-teavm.properties create mode 100644 example/lib-test/lib-teavm/src/main/resources/META-INF/teavm.properties diff --git a/.gitignore b/.gitignore index 0e47b640..251ddf3d 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,5 @@ out/ **/lib/lib-teavm/src/main/java/emu/** **/lib/lib-core/src/main/java/** **/app/android/libs/ +**/lib-test/lib-teavm/src/main/java/emu/** +**/lib-test/lib-core/src/main/java/** \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 91a9f1f6..724a296d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -39,7 +39,11 @@ allprojects() { } } -configure(allprojects - project(":example:app:android") - project(":example:lib:lib-android")) { +configure(allprojects + - project(":example:app:android") + - project(":example:lib:lib-android") + - project(":example:lib-test:lib-android") +) { apply { plugin("java") } diff --git a/example/lib-test/lib-android/build.gradle.kts b/example/lib-test/lib-android/build.gradle.kts new file mode 100644 index 00000000..fb8feb26 --- /dev/null +++ b/example/lib-test/lib-android/build.gradle.kts @@ -0,0 +1,31 @@ +plugins { + id("com.android.library") + kotlin("android") +} + +group = "lib.escripte" + +android { + namespace = "lib.escripten" + compileSdk = 33 + + defaultConfig { + minSdk = 21 + } + + sourceSets { + named("main") { + jniLibs.srcDirs("$projectDir/../lib-build/build/c++/libs/android") + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" + } +} + +dependencies { +} \ No newline at end of file diff --git a/example/lib-test/lib-base/build.gradle.kts b/example/lib-test/lib-base/build.gradle.kts new file mode 100644 index 00000000..27df264c --- /dev/null +++ b/example/lib-test/lib-base/build.gradle.kts @@ -0,0 +1,10 @@ +dependencies { + if(LibExt.exampleUseRepoLibs) { + implementation("com.github.xpenatan.jParser:base:${LibExt.libVersion}") + implementation("com.github.xpenatan.jParser:loader-core:${LibExt.libVersion}") + } + else { + implementation(project(":jParser:base")) + implementation(project(":jParser:loader:loader-core")) + } +} \ No newline at end of file diff --git a/example/lib-test/lib-base/src/main/java/lib/emscripten/TestLibLoader.java b/example/lib-test/lib-base/src/main/java/lib/emscripten/TestLibLoader.java new file mode 100644 index 00000000..2094a3c4 --- /dev/null +++ b/example/lib-test/lib-base/src/main/java/lib/emscripten/TestLibLoader.java @@ -0,0 +1,42 @@ +package lib.emscripten; + +import com.github.xpenatan.jparser.loader.JParserLibraryLoader; + +public class TestLibLoader { + + /*[-JNI;-NATIVE] + #include "CustomCode.h" + */ + + /*[-TEAVM;-ADD] + @org.teavm.jso.JSFunctor + public interface OnInitFunction extends org.teavm.jso.JSObject { + void onInit(); + } + */ + + /*[-TEAVM;-REPLACE] + public static void init(Runnable onSuccess) { + JParserLibraryLoader libraryLoader = new JParserLibraryLoader(); + OnInitFunction onInitFunction = () -> onSuccess.run(); + setOnLoadInit(onInitFunction); + libraryLoader.load("test.wasm", isSuccess -> {}); + } + */ + + public static void init(Runnable onSuccess) { + JParserLibraryLoader libraryLoader = new JParserLibraryLoader(); + libraryLoader.load("test", isSuccess -> { + if(isSuccess) { + onSuccess.run(); + } + }); + } + + /*[-TEAVM;-REPLACE] + @org.teavm.jso.JSBody(params = { "onInitFunction" }, script = "window.exampleLibOnInit = onInitFunction;") + private static native void setOnLoadInit(OnInitFunction onInitFunction); + */ + /*[-JNI;-REMOVE] */ + public static native void setOnLoadInit(); +} \ No newline at end of file diff --git a/example/lib-test/lib-build/build.gradle.kts b/example/lib-test/lib-build/build.gradle.kts new file mode 100644 index 00000000..fb4904a2 --- /dev/null +++ b/example/lib-test/lib-build/build.gradle.kts @@ -0,0 +1,98 @@ +plugins { + id("java") +} + +val mainClassName = "BuildLib" + +dependencies { + implementation(project(":example:lib-test:lib-base")) + + if(LibExt.exampleUseRepoLibs) { + implementation("com.github.xpenatan.jParser:core:${LibExt.libVersion}") + implementation("com.github.xpenatan.jParser:idl:${LibExt.libVersion}") + implementation("com.github.xpenatan.jParser:teavm:${LibExt.libVersion}") + implementation("com.github.xpenatan.jParser:cpp:${LibExt.libVersion}") + implementation("com.github.xpenatan.jParser:builder:${LibExt.libVersion}") + implementation("com.github.xpenatan.jParser:builder-tool:${LibExt.libVersion}") + } + else { + implementation(project(":jParser:core")) + implementation(project(":jParser:idl")) + implementation(project(":jParser:teavm")) + implementation(project(":jParser:cpp")) + implementation(project(":jParser:builder")) + implementation(project(":jParser:builder-tool")) + } +} + +tasks.register("build_project") { + group = "lib" + description = "Generate native project" + mainClass.set(mainClassName) + args = mutableListOf() + classpath = sourceSets["main"].runtimeClasspath +} + +tasks.register("build_project_all") { + group = "lib" + description = "Generate native project" + mainClass.set(mainClassName) + args = mutableListOf("teavm", "windows64", "linux64", "mac64", "macArm", "android", "ios") + classpath = sourceSets["main"].runtimeClasspath +} + +tasks.register("build_project_teavm") { + group = "lib" + description = "Generate native project" + mainClass.set(mainClassName) + args = mutableListOf("teavm") + classpath = sourceSets["main"].runtimeClasspath +} + +tasks.register("build_project_windows64") { + group = "lib" + description = "Generate native project" + mainClass.set(mainClassName) + args = mutableListOf("windows64") + classpath = sourceSets["main"].runtimeClasspath +} + +tasks.register("build_project_linux64") { + group = "lib" + description = "Generate native project" + mainClass.set(mainClassName) + args = mutableListOf("linux64") + classpath = sourceSets["main"].runtimeClasspath +} + +tasks.register("build_project_mac64") { + group = "lib" + description = "Generate native project" + mainClass.set(mainClassName) + args = mutableListOf("mac64") + classpath = sourceSets["main"].runtimeClasspath +} + +tasks.register("build_project_macArm") { + group = "lib" + description = "Generate native project" + mainClass.set(mainClassName) + args = mutableListOf("macArm") + classpath = sourceSets["main"].runtimeClasspath +} + +tasks.register("build_project_android") { + group = "lib" + description = "Generate native project" + mainClass.set(mainClassName) + args = mutableListOf("android") + classpath = sourceSets["main"].runtimeClasspath +} + +tasks.register("build_project_ios") { + group = "lib" + description = "Generate native project" + mainClass.set(mainClassName) + args = mutableListOf("ios") + classpath = sourceSets["main"].runtimeClasspath +} \ No newline at end of file diff --git a/example/lib-test/lib-build/src/main/cpp/custom/CustomCode.cpp b/example/lib-test/lib-build/src/main/cpp/custom/CustomCode.cpp new file mode 100644 index 00000000..9df9a23a --- /dev/null +++ b/example/lib-test/lib-build/src/main/cpp/custom/CustomCode.cpp @@ -0,0 +1 @@ +#include "CustomCode.h" \ No newline at end of file diff --git a/example/lib-test/lib-build/src/main/cpp/custom/CustomCode.h b/example/lib-test/lib-build/src/main/cpp/custom/CustomCode.h new file mode 100644 index 00000000..001b9b6c --- /dev/null +++ b/example/lib-test/lib-build/src/main/cpp/custom/CustomCode.h @@ -0,0 +1,4 @@ +#include "test.h" + +typedef EnumClass::EnumWithinClass EnumClass_EnumWithinClass; +typedef EnumNamespace::EnumInNamespace EnumNamespace_EnumInNamespace; \ No newline at end of file diff --git a/example/lib-test/lib-build/src/main/cpp/source/test/src/test.cpp b/example/lib-test/lib-build/src/main/cpp/source/test/src/test.cpp new file mode 100644 index 00000000..9fb03a03 --- /dev/null +++ b/example/lib-test/lib-build/src/main/cpp/source/test/src/test.cpp @@ -0,0 +1,15 @@ +// THIS FILE WAS DOWNLOADED FROM EMSCRIPTEN WEBIDL TEST (09/AUG/2024) + +#include "test.h" + +Parent::Parent(int val) : value(val), attr(6), immutableAttr(8) { + printf("Parent:%d\n", val); +} + +Parent::Parent(Parent* p, Parent* q) + : value(p->value + q->value), attr(6), immutableAttr(8) { + printf("Parent:%d\n", value); +} + +void Parent::mulVal(int mul) { value *= mul; } + diff --git a/example/lib-test/lib-build/src/main/cpp/source/test/src/test.h b/example/lib-test/lib-build/src/main/cpp/source/test/src/test.h new file mode 100644 index 00000000..b1b646ed --- /dev/null +++ b/example/lib-test/lib-build/src/main/cpp/source/test/src/test.h @@ -0,0 +1,243 @@ +// THIS FILE WAS DOWNLOADED FROM EMSCRIPTEN WEBIDL TEST (09/AUG/2024) + +#include +#include + +// Part 1 + +class Parent { +protected: + int value; +public: + Parent(int val); + Parent(Parent *p, Parent *q); // overload constructor + int getVal() { return value; }; // inline should work just fine here, unlike Way 1 before + void mulVal(int mul); + void parentFunc() {} + const Parent *getAsConst() { return NULL; } + void *voidStar(void *something) { return something; } + bool getBoolean() { return true; } + int attr; + const int immutableAttr; +}; + +class Child1 : public Parent { +public: + Child1() : Parent(7) { printf("Child1:%d\n", value); }; + Child1(int val) : Parent(val*2) { value -= 1; printf("Child1:%d\n", value); }; + int getValSqr() { return value*value; } + int getValSqr(int more) { return value*value*more; } + int getValTimes(int times=1) { return value*times; } + void parentFunc(int x) { printf("Child1::parentFunc(%d)\n", x); } +}; + +// Child2 has vtable, parent does not. Checks we cast child->parent properly - (Parent*)child is not a no-op, must offset +class Child2 : public Parent { +public: + Child2() : Parent(9) { printf("Child2:%d\n", value); }; + virtual ~Child2() = default; + int getValCube() { return value*value*value; } + static void printStatic(int arg0) { printf("*static*: %d\n", arg0); } + + virtual void virtualFunc() { printf("*virtualf*\n"); } + virtual void virtualFunc2() { printf("*virtualf2*\n"); } + static void runVirtualFunc(Child2 *self) { self->virtualFunc(); }; + virtual void virtualFunc3(int x) { printf("*virtualf3: %d*\n", x); } + virtual void virtualFunc4(int x) { printf("*virtualf4: %d*\n", x); } + static void runVirtualFunc3(Child2 *self, int x) { self->virtualFunc3(x); } + +private: + void doSomethingSecret() { printf("security breached!\n"); }; // we should not be able to do this +}; + +// We test compilation here: abstract base classes must be handled properly, +// and in particular the const property may matter (if not overridden as +// const, compilation will fail). +class VirtualBase { +public: + virtual ~VirtualBase() {}; + + virtual void func() = 0; + virtual void constFunc() const = 0; +}; + +// Part 2 + +#include + +class StringUser { + char *s; + int i; +public: + StringUser(const char *string="NO", int integer=99) : s(strdup(string)), i(integer) {} + ~StringUser() { free(s); } + void Print(int anotherInteger, char *anotherString) { + printf("|%s|%d|%s|%d|\n", s, i, anotherString, anotherInteger); + } + void PrintFloat(float f) { printf("%.2f\n", f); } + const char* returnAString() { return "a returned string"; } +}; + +struct RefUser { + int value; + RefUser(int x = 77) : value(x) {} + int getValue(RefUser b) { return b.value; } + RefUser &getMe() { return *this; } + RefUser getCopy() { return RefUser(value*2); } + StringUser getAnother() { return StringUser("another", 5); } +}; + +struct VoidPointerUser { + void *ptr; + + void *GetVoidPointer() { return ptr; } + void SetVoidPointer(void *p) { ptr = p; } +}; + +namespace Space { + struct Inner { + int value; + Inner() : value(1) {} + int get() { return 198; } + Inner& operator*=(float x) { return *this; } + int operator[](int x) { return x*2; } + void operator+=(const Inner& other) { + value += other.value; + printf("Inner::+= => %d\n", value); + } + }; + + // We test compilation of abstract base classes in a namespace here. + class InnerUserBase { + public: + virtual ~InnerUserBase() {}; + + virtual void Callback(Inner *inner) = 0; + }; +} + +enum AnEnum { + enum_value1, + enum_value2 +}; + +namespace EnumNamespace { + enum EnumInNamespace { + e_namespace_val = 78 + }; +}; + +class EnumClass { +public: + enum EnumWithinClass { + e_val = 34 + }; + EnumWithinClass GetEnum() { return e_val; } + + EnumNamespace::EnumInNamespace GetEnumFromNameSpace() { return EnumNamespace::e_namespace_val; } +}; + +class TypeTestClass { +public: + char ReturnCharMethod() { return (2<<6)-1; } + void AcceptCharMethod(char x) { printf("char: %d\n", x); } + + unsigned char ReturnUnsignedCharMethod() { return (2<<7)-1; } + void AcceptUnsignedCharMethod(unsigned char x) { printf("unsigned char: %u\n", x); } + + unsigned short int ReturnUnsignedShortMethod() { return (2<<15)-1; } + void AcceptUnsignedShortMethod(unsigned short x) { printf("unsigned short int: %u\n", x); } + + unsigned long ReturnUnsignedLongMethod() { return 0xffffffff; } + void AcceptUnsignedLongMethod(unsigned long x) { printf("unsigned long int: %lu\n", x); } +}; + +struct StructInArray { + StructInArray() : attr1(0), attr2(0) {} + StructInArray(int _attr1, int _attr2) : attr1(_attr1), attr2(_attr2) {} + int attr1; + int attr2; +}; + +class ArrayClass { +public: + ArrayClass() { + for (int i = 0; i < 8; i++) { + int_array[i] = i; + struct_array[i] = StructInArray(i, -i); + struct_ptr_array[i] = NULL; + } + } + int int_array[8]; + StructInArray struct_array[8]; + StructInArray* struct_ptr_array[8]; +}; + +struct ReceiveArrays { + void giveMeArrays(float* vertices, int* triangles, int num) { + for (int i = 0; i < num; i++) { + printf("%d : %.2f\n", triangles[i], vertices[i]); + } + } +}; + +struct StoreArray { + StoreArray() : int_array(NULL) {} + void setArray(const int *array) { + int_array = array; + } + int getArrayValue(int index) const { + return int_array[index]; + } + const int* int_array; +}; + +typedef struct LongLongTypes { + unsigned long long* lluArray; + long long ll; +} LongLongTypes; + +// Returning child objects in a hierarchy + +struct ISmallObject { + virtual int getID(int number) = 0; +}; + +struct IObjectProvider { + virtual ISmallObject* getObject() = 0; +}; + +class SmallObject : public ISmallObject { +public: + int getID(int number) { + return number; + } +}; + +class ObjectProvider : public IObjectProvider { +public: + ISmallObject* getObject() { + return &m_smallObject; + } +private: + SmallObject m_smallObject; +}; + +class ObjectFactory { +public: + IObjectProvider* getProvider() { + return &m_ObjectProvider; + } +private: + ObjectProvider m_ObjectProvider; +}; + +class ArrayArgumentTest { +public: + ArrayArgumentTest() : m_array("I should match the member variable"){}; + ~ArrayArgumentTest(){}; + bool byteArrayTest(const char* arg) { return strcmp(arg, m_array) == 0; } + bool domStringTest(const char* arg) { return strcmp(arg, m_array) == 0; } +private: + const char* m_array; +}; \ No newline at end of file diff --git a/example/lib-test/lib-build/src/main/cpp/test.idl b/example/lib-test/lib-build/src/main/cpp/test.idl new file mode 100644 index 00000000..32230ff5 --- /dev/null +++ b/example/lib-test/lib-build/src/main/cpp/test.idl @@ -0,0 +1,212 @@ +// THIS FILE WAS DOWNLOADED FROM EMSCRIPTEN WEBIDL TEST (09/AUG/2024) + +// Part 1 + +interface Parent { + void Parent(long val); + long getVal(); + void mulVal(long mul); + void parentFunc(); + [Const] Parent getAsConst(); + VoidPtr voidStar(VoidPtr something); + boolean getBoolean(); + attribute long attr; + readonly attribute long immutableAttr; +}; + +interface Child1 { + void Child1(optional long val); + long getValSqr(optional long more); +// long getValTimes(optional long times=1); + void parentFunc(long x); // redefinition, name collides with parent +}; + +Child1 implements Parent; + +interface Child2 { + void Child2(); + long getValCube(); + static void printStatic(long arg0); + void virtualFunc(); + void virtualFunc2(); + void virtualFunc3(long x); + void virtualFunc4(long x); + static void runVirtualFunc(Child2 myself); + static void runVirtualFunc3(Child2 myself, long x); +}; + +Child2 implements Parent; + +[JSImplementation="Child2"] +interface Child2JS { + void Child2JS(); + void virtualFunc(); + void virtualFunc2(); + void virtualFunc3(long x); + void virtualFunc4(long x); +}; + +interface VirtualBase { + void func(); + void constFunc(); +}; + +[JSImplementation="VirtualBase"] +interface ConcreteJS { + void ConcreteJS(); + void func(); + [Const] void constFunc(); +}; + +// Part 2 + +interface StringUser { + void StringUser(); + void StringUser(DOMString str, long i); + void Print(long anotherInteger, DOMString anotherString); + void PrintFloat(float f); +// [Const] DOMString returnAString(); +}; + +interface RefUser { + void RefUser(); + void RefUser(long value); + long getValue([Ref] RefUser b); + [Ref] RefUser getMe(); + [Value] RefUser getCopy(); // must have zero-arg constructor + [Value] StringUser getAnother(); +}; + +interface VoidPointerUser { + void VoidPointerUser(); + + any GetVoidPointer(); + void SetVoidPointer(any ptr); +}; + +[Prefix="Space::"] +interface Inner { + void Inner(); + long get(); +// [Operator="*=", Ref] Inner mul(float x); +// [Operator="[]"] long getAsArray(long x); +// [Operator="+="] void incInPlace([Const, Ref] Inner i); +}; + +[Prefix = "Space::"] +interface InnerUserBase { +}; + +[JSImplementation = "InnerUserBase"] +interface InnerUser { + void InnerUser(); + void Callback(Inner inner); +}; + +enum AnEnum { + "enum_value1", + "enum_value2" +}; + +enum EnumClass_EnumWithinClass { + "EnumClass::e_val" +}; + +enum EnumNamespace_EnumInNamespace { + "EnumNamespace::e_namespace_val" +}; + +interface EnumClass { + void EnumClass(); + + EnumClass_EnumWithinClass GetEnum(); + + EnumNamespace_EnumInNamespace GetEnumFromNameSpace(); +}; + +interface TypeTestClass { + void TypeTestClass(); + + byte ReturnCharMethod(); + void AcceptCharMethod(byte x); + +// octet ReturnUnsignedCharMethod(); +// void AcceptUnsignedCharMethod(octet x); + + unsigned short ReturnUnsignedShortMethod(); + void AcceptUnsignedShortMethod(unsigned short x); + + unsigned long ReturnUnsignedLongMethod(); + void AcceptUnsignedLongMethod(unsigned long x); +}; + +interface StructInArray { + void StructInArray(long attr1, long attr2); + attribute long attr1; + attribute long attr2; +}; + +interface ArrayClass { + void ArrayClass(); +// [BoundsChecked] attribute long[] int_array; +// [Value] attribute StructInArray[] struct_array; +// attribute StructInArray[] struct_ptr_array; +}; + +interface ReceiveArrays { + void ReceiveArrays(); + + void giveMeArrays(float[] vertices, long[] triangles, long num); +}; + +interface StoreArray { + void StoreArray(); + + void setArray([Const] long[] array); + long getArrayValue(long index); +}; + +interface LongLongTypes { +// readonly attribute unsigned long long[] lluArray; + attribute long long ll; +}; + +[NoDelete] +interface ISmallObject { + long getID(long number); +}; + +[JSImplementation="ISmallObject"] +interface JSSmallObject { + void JSSmallObject(); + long getID(long number); +}; + +[NoDelete] +interface IObjectProvider { + ISmallObject getObject(); +}; + +[JSImplementation="IObjectProvider"] +interface JSObjectProvider { + void JSObjectProvider(); + JSSmallObject getObject(); +}; + +interface ObjectFactory { + void ObjectFactory(); + IObjectProvider getProvider(); +}; + +interface ArrayArgumentTest { + void ArrayArgumentTest(); + boolean byteArrayTest([Const] byte[] arg); + boolean domStringTest([Const] DOMString arg); +}; + +[JSImplementation = "ArrayArgumentTest"] +interface JSArrayArgumentTest { + void JSArrayArgumentTest(); + boolean byteArrayTest([Const] byte[] arg); + boolean domStringTest([Const] DOMString arg); +}; \ No newline at end of file diff --git a/example/lib-test/lib-build/src/main/java/BuildLib.java b/example/lib-test/lib-build/src/main/java/BuildLib.java new file mode 100644 index 00000000..1a43cc04 --- /dev/null +++ b/example/lib-test/lib-build/src/main/java/BuildLib.java @@ -0,0 +1,187 @@ +import com.github.xpenatan.jparser.builder.BuildMultiTarget; +import com.github.xpenatan.jparser.builder.targets.AndroidTarget; +import com.github.xpenatan.jparser.builder.targets.EmscriptenTarget; +import com.github.xpenatan.jparser.builder.targets.IOSTarget; +import com.github.xpenatan.jparser.builder.targets.LinuxTarget; +import com.github.xpenatan.jparser.builder.targets.MacTarget; +import com.github.xpenatan.jparser.builder.targets.WindowsTarget; +import com.github.xpenatan.jparser.builder.tool.BuildToolListener; +import com.github.xpenatan.jparser.builder.tool.BuildToolOptions; +import com.github.xpenatan.jparser.builder.tool.BuilderTool; +import com.github.xpenatan.jparser.idl.IDLReader; +import java.util.ArrayList; + +public class BuildLib { + + public static void main(String[] args) throws Exception { + String libName = "test"; + String modulePrefix = "lib"; + String basePackage = "lib.test"; + String sourceDir = "/src/main/cpp/source/test/src"; + BuildToolOptions op = new BuildToolOptions(libName, basePackage, modulePrefix, sourceDir, args); + BuilderTool.build(op, new BuildToolListener() { + @Override + public void onAddTarget(BuildToolOptions op, IDLReader idlReader, ArrayList targets) { + if(op.teavm) { + targets.add(getTeavmTarget(op, idlReader)); + } + if(op.windows64) { + targets.add(getWindowTarget(op)); + } + if(op.linux64) { + targets.add(getLinuxTarget(op)); + } + if(op.mac64) { + targets.add(getMacTarget(op, false)); + } + if(op.macArm) { + targets.add(getMacTarget(op, true)); + } + if(op.android) { + targets.add(getAndroidTarget(op)); + } + if(op.iOS) { + targets.add(getIOSTarget(op)); + } + } + }); + } + + private static BuildMultiTarget getWindowTarget(BuildToolOptions op) { + BuildMultiTarget multiTarget = new BuildMultiTarget(); + + String libBuildCPPPath = op.getModuleBuildCPPPath(); + + // Make a static library + WindowsTarget compileStaticTarget = new WindowsTarget(); + compileStaticTarget.isStatic = true; + compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); + compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/test/**.cpp"); + multiTarget.add(compileStaticTarget); + + WindowsTarget linkTarget = new WindowsTarget(); + linkTarget.addJNIHeaders(); + linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); + linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/jniglue"); + linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/windows/" + op.libName + "64.a"); + linkTarget.cppInclude.add(libBuildCPPPath + "/src/jniglue/JNIGlue.cpp"); + + multiTarget.add(linkTarget); + return multiTarget; + } + + private static BuildMultiTarget getLinuxTarget(BuildToolOptions op) { + BuildMultiTarget multiTarget = new BuildMultiTarget(); + + String libBuildCPPPath = op.getModuleBuildCPPPath(); + + // Make a static library + LinuxTarget compileStaticTarget = new LinuxTarget(); + compileStaticTarget.isStatic = true; + compileStaticTarget.headerDirs.add("-Isrc/test"); + compileStaticTarget.cppInclude.add("**/src/test/**.cpp"); + multiTarget.add(compileStaticTarget); + + LinuxTarget linkTarget = new LinuxTarget(); + linkTarget.addJNIHeaders(); + linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); + linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/jniglue"); + linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/linux/lib" + op.libName + "64.a"); + linkTarget.cppInclude.add(libBuildCPPPath + "/src/jniglue/JNIGlue.cpp"); + + multiTarget.add(linkTarget); + + return multiTarget; + } + + private static BuildMultiTarget getMacTarget(BuildToolOptions op, boolean isArm) { + BuildMultiTarget multiTarget = new BuildMultiTarget(); + + String libBuildCPPPath = op.getModuleBuildCPPPath(); + + // Make a static library + MacTarget compileStaticTarget = new MacTarget(isArm); + compileStaticTarget.isStatic = true; + compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); + compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/test/**.cpp"); + multiTarget.add(compileStaticTarget); + + MacTarget linkTarget = new MacTarget(isArm); + linkTarget.addJNIHeaders(); + linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); + linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/jniglue"); + + if(isArm) { + linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/mac/arm/lib" + op.libName + "64.a"); + } + else { + linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/mac/lib" + op.libName + "64.a"); + } + linkTarget.cppInclude.add(libBuildCPPPath + "/src/jniglue/JNIGlue.cpp"); + + multiTarget.add(linkTarget); + + return multiTarget; + } + + private static BuildMultiTarget getTeavmTarget(BuildToolOptions op, IDLReader idlReader) { + BuildMultiTarget multiTarget = new BuildMultiTarget(); + + String libBuildCPPPath = op.getModuleBuildCPPPath(); + + // Make a static library + EmscriptenTarget compileStaticTarget = new EmscriptenTarget(idlReader); + compileStaticTarget.isStatic = true; + compileStaticTarget.compileGlueCode = false; + compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); + compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/test/**.cpp"); + multiTarget.add(compileStaticTarget); + + // Compile glue code and link to make js file + EmscriptenTarget linkTarget = new EmscriptenTarget(idlReader); + linkTarget.headerDirs.add("-include" + libBuildCPPPath + "/src/test/CustomCode.h"); + linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/emscripten/" + op.libName + ".a"); + multiTarget.add(linkTarget); + return multiTarget; + } + + private static BuildMultiTarget getAndroidTarget(BuildToolOptions op) { + BuildMultiTarget multiTarget = new BuildMultiTarget(); + + String libBuildCPPPath = op.getModuleBuildCPPPath(); + + AndroidTarget androidTarget = new AndroidTarget(); + androidTarget.addJNIHeaders(); + androidTarget.headerDirs.add(libBuildCPPPath + "/src/test"); + androidTarget.cppInclude.add(libBuildCPPPath + "/src/test/**.cpp"); + + multiTarget.add(androidTarget); + + return multiTarget; + } + + private static BuildMultiTarget getIOSTarget(BuildToolOptions op) { + String libBuildCPPPath = op.getModuleBuildCPPPath(); + // TODO WIP/not working + + BuildMultiTarget multiTarget = new BuildMultiTarget(); + + // Make a static library + IOSTarget compileStaticTarget = new IOSTarget(); + compileStaticTarget.isStatic = true; + compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); + compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/test/**.cpp"); + multiTarget.add(compileStaticTarget); + + IOSTarget linkTarget = new IOSTarget(); + linkTarget.addJNIHeaders(); + linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); + linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/jniglue"); + linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/ios/lib" + op.libName + ".a"); + linkTarget.cppInclude.add(libBuildCPPPath + "/src/jniglue/JNIGlue.cpp"); + + multiTarget.add(linkTarget); + + return multiTarget; + } +} \ No newline at end of file diff --git a/example/lib-test/lib-core/build.gradle.kts b/example/lib-test/lib-core/build.gradle.kts new file mode 100644 index 00000000..eba178a5 --- /dev/null +++ b/example/lib-test/lib-core/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + id("java") +} + +dependencies { + if(LibExt.exampleUseRepoLibs) { + implementation("com.github.xpenatan.jParser:loader-core:${LibExt.libVersion}") + } + else { + implementation(project(":jParser:loader:loader-core")) + } +} + +tasks.named("clean") { + doFirst { + val srcPath = "$projectDir/src/main/" + project.delete(files(srcPath)) + } +} \ No newline at end of file diff --git a/example/lib-test/lib-desktop/build.gradle.kts b/example/lib-test/lib-desktop/build.gradle.kts new file mode 100644 index 00000000..b7f5a033 --- /dev/null +++ b/example/lib-test/lib-desktop/build.gradle.kts @@ -0,0 +1,34 @@ +plugins { + id("java") +} + +val libDir = "${projectDir}/../lib-build/build/c++/libs" +val windowsFile = "$libDir/windows/test64.dll" +val linuxFile = "$libDir/linux/libtest64.so" +val macFile = "$libDir/mac/libtest64.dylib" +val macArmFile = "$libDir/mac/arm/libtestarm64.dylib" + +tasks.jar { + from(windowsFile) + from(linuxFile) + from(macFile) + from(macArmFile) +} + +dependencies { + if(LibExt.exampleUseRepoLibs) { + testImplementation("com.github.xpenatan.jParser:loader-core:${LibExt.libVersion}") + } + else { + testImplementation(project(":jParser:loader:loader-core")) + } + testImplementation(project(":example:lib-test:lib-core")) + testImplementation("junit:junit:${LibExt.jUnitVersion}") +} + +tasks.named("clean") { + doFirst { + val srcPath = "$projectDir/src/main/" + project.delete(files(srcPath)) + } +} \ No newline at end of file diff --git a/example/lib-test/lib-teavm/build.gradle.kts b/example/lib-test/lib-teavm/build.gradle.kts new file mode 100644 index 00000000..a71546f3 --- /dev/null +++ b/example/lib-test/lib-teavm/build.gradle.kts @@ -0,0 +1,35 @@ +plugins { + id("java") +} + +val emscriptenFile = "$projectDir/../lib-build/build/c++/libs/emscripten/test.wasm.js" + +tasks.jar { + from(emscriptenFile) +} + +dependencies { + implementation("org.teavm:teavm-jso:${LibExt.teaVMVersion}") + implementation(project(":jParser:loader:loader-teavm")) + implementation("org.teavm:teavm-classlib:${LibExt.teaVMVersion}") + + if(LibExt.exampleUseRepoLibs) { + implementation("com.github.xpenatan.jParser:loader-core:${LibExt.libVersion}") + } + else { + implementation(project(":jParser:loader:loader-core")) + } + testImplementation(project(":example:lib-test:lib-core")) + testImplementation("junit:junit:${LibExt.jUnitVersion}") + testImplementation("org.teavm:teavm-core:${LibExt.teaVMVersion}") + testImplementation("org.teavm:teavm-jso-apis:${LibExt.teaVMVersion}") + testImplementation("org.teavm:teavm-classlib:${LibExt.teaVMVersion}") + testImplementation("org.teavm:teavm-junit:${LibExt.teaVMVersion}") +} + +tasks.named("clean") { + doFirst { + val srcPath = "$projectDir/src/main/java/gen" + project.delete(files(srcPath)) + } +} \ No newline at end of file diff --git a/example/lib-test/lib-teavm/src/main/resources/META-INF/gdx-teavm.properties b/example/lib-test/lib-teavm/src/main/resources/META-INF/gdx-teavm.properties new file mode 100644 index 00000000..e69de29b diff --git a/example/lib-test/lib-teavm/src/main/resources/META-INF/teavm.properties b/example/lib-test/lib-teavm/src/main/resources/META-INF/teavm.properties new file mode 100644 index 00000000..22ff4f62 --- /dev/null +++ b/example/lib-test/lib-teavm/src/main/resources/META-INF/teavm.properties @@ -0,0 +1 @@ +mapPackageHierarchy|gen.com=com diff --git a/settings.gradle.kts b/settings.gradle.kts index 25cee29a..1bfdbf6f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -15,6 +15,13 @@ include(":example:lib:lib-desktop") include(":example:lib:lib-teavm") include(":example:lib:lib-android") +include(":example:lib-test:lib-build") +include(":example:lib-test:lib-base") +include(":example:lib-test:lib-core") +include(":example:lib-test:lib-desktop") +include(":example:lib-test:lib-teavm") +include(":example:lib-test:lib-android") + //include(":example:lib-ext:ext-base") //include(":example:lib-ext:ext-build") //include(":example:lib-ext:ext-core") From 79964b4d3982dac782fe0589701a73cb14b8abbc Mon Sep 17 00:00:00 2001 From: Natan Date: Fri, 9 Aug 2024 20:32:27 -0300 Subject: [PATCH 041/186] Rename source folder --- .../src/main/cpp/source/{test => testLib}/src/test.cpp | 0 .../lib-build/src/main/cpp/source/{test => testLib}/src/test.h | 0 example/lib-test/lib-build/src/main/java/BuildLib.java | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) rename example/lib-test/lib-build/src/main/cpp/source/{test => testLib}/src/test.cpp (100%) rename example/lib-test/lib-build/src/main/cpp/source/{test => testLib}/src/test.h (100%) diff --git a/example/lib-test/lib-build/src/main/cpp/source/test/src/test.cpp b/example/lib-test/lib-build/src/main/cpp/source/testLib/src/test.cpp similarity index 100% rename from example/lib-test/lib-build/src/main/cpp/source/test/src/test.cpp rename to example/lib-test/lib-build/src/main/cpp/source/testLib/src/test.cpp diff --git a/example/lib-test/lib-build/src/main/cpp/source/test/src/test.h b/example/lib-test/lib-build/src/main/cpp/source/testLib/src/test.h similarity index 100% rename from example/lib-test/lib-build/src/main/cpp/source/test/src/test.h rename to example/lib-test/lib-build/src/main/cpp/source/testLib/src/test.h diff --git a/example/lib-test/lib-build/src/main/java/BuildLib.java b/example/lib-test/lib-build/src/main/java/BuildLib.java index 1a43cc04..cb935942 100644 --- a/example/lib-test/lib-build/src/main/java/BuildLib.java +++ b/example/lib-test/lib-build/src/main/java/BuildLib.java @@ -17,7 +17,7 @@ public static void main(String[] args) throws Exception { String libName = "test"; String modulePrefix = "lib"; String basePackage = "lib.test"; - String sourceDir = "/src/main/cpp/source/test/src"; + String sourceDir = "/src/main/cpp/source/testLib/src"; BuildToolOptions op = new BuildToolOptions(libName, basePackage, modulePrefix, sourceDir, args); BuilderTool.build(op, new BuildToolListener() { @Override From 218230f4ed3f5b05a62e5fb8f7d6ead7dcdc550b Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 10 Aug 2024 11:49:11 -0300 Subject: [PATCH 042/186] add test app --- .gitignore | 3 +- build.gradle.kts | 1 + example/app-test/android/build.gradle.kts | 76 ++++ example/app-test/android/proguard-rules.pro | 21 + .../android/src/main/AndroidManifest.xml | 19 + .../example/myapplication/MainActivity.kt | 16 + .../drawable-v24/ic_launcher_foreground.xml | 31 ++ .../res/drawable/ic_launcher_background.xml | 74 ++++ .../src/main/res/layout/activity_main.xml | 10 + .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../res/mipmap-anydpi-v33/ic_launcher.xml | 6 + .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 1404 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 2898 bytes .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 982 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 1772 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 1900 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 3918 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 2884 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 5914 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 3844 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 7778 bytes .../android/src/main/res/values/colors.xml | 10 + .../android/src/main/res/values/strings.xml | 3 + example/app-test/core/build.gradle.kts | 5 + .../jparser/example/app/AppTestLib.java | 375 ++++++++++++++++++ .../app-test/desktop/assets/data/badlogic.jpg | Bin 0 -> 68465 bytes example/app-test/desktop/build.gradle.kts | 22 + .../xpenatan/jparser/example/app/Main.java | 12 + example/app-test/teavm/build.gradle.kts | 34 ++ .../app-test/teavm/src/main/java/Build.java | 21 + .../teavm/src/main/java/TeaVMLauncher.java | 13 + settings.gradle.kts | 5 + 33 files changed, 766 insertions(+), 1 deletion(-) create mode 100644 example/app-test/android/build.gradle.kts create mode 100644 example/app-test/android/proguard-rules.pro create mode 100644 example/app-test/android/src/main/AndroidManifest.xml create mode 100644 example/app-test/android/src/main/kotlin/lib.test.android/example/myapplication/MainActivity.kt create mode 100644 example/app-test/android/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 example/app-test/android/src/main/res/drawable/ic_launcher_background.xml create mode 100644 example/app-test/android/src/main/res/layout/activity_main.xml create mode 100644 example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 example/app-test/android/src/main/res/mipmap-anydpi-v33/ic_launcher.xml create mode 100644 example/app-test/android/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 example/app-test/android/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 example/app-test/android/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 example/app-test/android/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 example/app-test/android/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 example/app-test/android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 example/app-test/android/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 example/app-test/android/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 example/app-test/android/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 example/app-test/android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 example/app-test/android/src/main/res/values/colors.xml create mode 100644 example/app-test/android/src/main/res/values/strings.xml create mode 100644 example/app-test/core/build.gradle.kts create mode 100644 example/app-test/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTestLib.java create mode 100644 example/app-test/desktop/assets/data/badlogic.jpg create mode 100644 example/app-test/desktop/build.gradle.kts create mode 100644 example/app-test/desktop/src/main/java/com/github/xpenatan/jparser/example/app/Main.java create mode 100644 example/app-test/teavm/build.gradle.kts create mode 100644 example/app-test/teavm/src/main/java/Build.java create mode 100644 example/app-test/teavm/src/main/java/TeaVMLauncher.java diff --git a/.gitignore b/.gitignore index 251ddf3d..c9b6bff3 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,5 @@ out/ **/lib/lib-core/src/main/java/** **/app/android/libs/ **/lib-test/lib-teavm/src/main/java/emu/** -**/lib-test/lib-core/src/main/java/** \ No newline at end of file +**/lib-test/lib-core/src/main/java/** +**/app-lib/android/libs/ diff --git a/build.gradle.kts b/build.gradle.kts index 724a296d..62b24af5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -43,6 +43,7 @@ configure(allprojects - project(":example:app:android") - project(":example:lib:lib-android") - project(":example:lib-test:lib-android") + - project(":example:app-test:android") ) { apply { plugin("java") diff --git a/example/app-test/android/build.gradle.kts b/example/app-test/android/build.gradle.kts new file mode 100644 index 00000000..e973e3ce --- /dev/null +++ b/example/app-test/android/build.gradle.kts @@ -0,0 +1,76 @@ +plugins { + id("com.android.application") + id("kotlin-android") +} + +group = "lib.test.android" + +android { + namespace = "lib.test.android" + compileSdk = 33 + + defaultConfig { + applicationId = "lib.test.android" + minSdk = 24 + targetSdk = 33 + versionCode = 1 + versionName = "1.0" + } + + sourceSets { + named("main") { +// java.srcDirs("src/main/kotlin") +// assets.srcDirs(project.file("../assets")) + jniLibs.srcDirs("libs") + } + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" + } +} +val natives: Configuration by configurations.creating + +dependencies { + coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3") + implementation("com.badlogicgames.gdx:gdx:${LibExt.gdxVersion}") + implementation("com.badlogicgames.gdx:gdx-backend-android:${LibExt.gdxVersion}") + natives("com.badlogicgames.gdx:gdx-platform:${LibExt.gdxVersion}:natives-armeabi-v7a") + natives("com.badlogicgames.gdx:gdx-platform:${LibExt.gdxVersion}:natives-arm64-v8a") + natives("com.badlogicgames.gdx:gdx-platform:${LibExt.gdxVersion}:natives-x86_64") + natives("com.badlogicgames.gdx:gdx-platform:${LibExt.gdxVersion}:natives-x86") + + implementation(project(":example:app-test:core")) + implementation(project(":example:lib-test:lib-android")) +} + + +tasks.register("copyAndroidNatives") { + doFirst { + natives.files.forEach { jar -> + val outputDir = file("libs/" + jar.nameWithoutExtension.substringAfterLast("natives-")) + outputDir.mkdirs() + copy { + from(zipTree(jar)) + into(outputDir) + include("*.so") + } + } + } +} + +tasks.whenTaskAdded { + if ("package" in name) { + dependsOn("copyAndroidNatives") + } +} \ No newline at end of file diff --git a/example/app-test/android/proguard-rules.pro b/example/app-test/android/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/example/app-test/android/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/example/app-test/android/src/main/AndroidManifest.xml b/example/app-test/android/src/main/AndroidManifest.xml new file mode 100644 index 00000000..bac4e34d --- /dev/null +++ b/example/app-test/android/src/main/AndroidManifest.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/app-test/android/src/main/kotlin/lib.test.android/example/myapplication/MainActivity.kt b/example/app-test/android/src/main/kotlin/lib.test.android/example/myapplication/MainActivity.kt new file mode 100644 index 00000000..d1c1c501 --- /dev/null +++ b/example/app-test/android/src/main/kotlin/lib.test.android/example/myapplication/MainActivity.kt @@ -0,0 +1,16 @@ +package com.example.myapplication + +import android.os.Bundle +import com.badlogic.gdx.backends.android.AndroidApplication +import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration +import com.github.xpenatan.jparser.example.app.AppTest + +class MainActivity : AndroidApplication() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + initialize(AppTest(), AndroidApplicationConfiguration().apply { + // Configure your application here. + useImmersiveMode = true // Recommended, but not required. + }) + } +} \ No newline at end of file diff --git a/example/app-test/android/src/main/res/drawable-v24/ic_launcher_foreground.xml b/example/app-test/android/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 00000000..09b36162 --- /dev/null +++ b/example/app-test/android/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/example/app-test/android/src/main/res/drawable/ic_launcher_background.xml b/example/app-test/android/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000..9c9f7c82 --- /dev/null +++ b/example/app-test/android/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/app-test/android/src/main/res/layout/activity_main.xml b/example/app-test/android/src/main/res/layout/activity_main.xml new file mode 100644 index 00000000..18e36833 --- /dev/null +++ b/example/app-test/android/src/main/res/layout/activity_main.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 00000000..bbd3e021 --- /dev/null +++ b/example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 00000000..bbd3e021 --- /dev/null +++ b/example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/example/app-test/android/src/main/res/mipmap-anydpi-v33/ic_launcher.xml b/example/app-test/android/src/main/res/mipmap-anydpi-v33/ic_launcher.xml new file mode 100644 index 00000000..50ec8862 --- /dev/null +++ b/example/app-test/android/src/main/res/mipmap-anydpi-v33/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/example/app-test/android/src/main/res/mipmap-hdpi/ic_launcher.webp b/example/app-test/android/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..c209e78ecd372343283f4157dcfd918ec5165bb3 GIT binary patch literal 1404 zcmV-?1%vuhNk&F=1pok7MM6+kP&il$0000G0000-002h-06|PpNX!5L00Dqw+t%{r zzW2vH!KF=w&cMnnN@{whkTw+#mAh0SV?YL=)3MimFYCWp#fpdtz~8$hD5VPuQgtcN zXl<@<#Cme5f5yr2h%@8TWh?)bSK`O z^Z@d={gn7J{iyxL_y_%J|L>ep{dUxUP8a{byupH&!UNR*OutO~0{*T4q5R6@ApLF! z5{w?Z150gC7#>(VHFJZ-^6O@PYp{t!jH(_Z*nzTK4 zkc{fLE4Q3|mA2`CWQ3{8;gxGizgM!zccbdQoOLZc8hThi-IhN90RFT|zlxh3Ty&VG z?Fe{#9RrRnxzsu|Lg2ddugg7k%>0JeD+{XZ7>Z~{=|M+sh1MF7~ zz>To~`~LVQe1nNoR-gEzkpe{Ak^7{{ZBk2i_<+`Bq<^GB!RYG+z)h;Y3+<{zlMUYd zrd*W4w&jZ0%kBuDZ1EW&KLpyR7r2=}fF2%0VwHM4pUs}ZI2egi#DRMYZPek*^H9YK zay4Iy3WXFG(F14xYsoDA|KXgGc5%2DhmQ1gFCkrgHBm!lXG8I5h*uf{rn48Z!_@ z4Bk6TJAB2CKYqPjiX&mWoW>OPFGd$wqroa($ne7EUK;#3VYkXaew%Kh^3OrMhtjYN?XEoY`tRPQsAkH-DSL^QqyN0>^ zmC>{#F14jz4GeW{pJoRpLFa_*GI{?T93^rX7SPQgT@LbLqpNA}<@2wH;q493)G=1Y z#-sCiRNX~qf3KgiFzB3I>4Z%AfS(3$`-aMIBU+6?gbgDb!)L~A)je+;fR0jWLL-Fu z4)P{c7{B4Hp91&%??2$v9iRSFnuckHUm}or9seH6 z>%NbT+5*@L5(I9j@06@(!{ZI?U0=pKn8uwIg&L{JV14+8s2hnvbRrU|hZCd}IJu7*;;ECgO%8_*W Kmw_-CKmY()leWbG literal 0 HcmV?d00001 diff --git a/example/app-test/android/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/example/app-test/android/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..b2dfe3d1ba5cf3ee31b3ecc1ced89044a1f3b7a9 GIT binary patch literal 2898 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 literal 0 HcmV?d00001 diff --git a/example/app-test/android/src/main/res/mipmap-mdpi/ic_launcher.webp b/example/app-test/android/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..4f0f1d64e58ba64d180ce43ee13bf9a17835fbca GIT binary patch literal 982 zcmV;{11bDcNk&G_0{{S5MM6+kP&il$0000G0000l001ul06|PpNU8t;00Dqo+t#w^ z^1csucXz7-Qrhzl9HuHB%l>&>1tG2^vb*E&k^T3$FG1eQZ51g$uv4V+kI`0<^1Z@N zk?Jjh$olyC%l>)Xq;7!>{iBj&BjJ`P&$fsCfpve_epJOBkTF?nu-B7D!hO=2ZR}

C%4 zc_9eOXvPbC4kzU8YowIA8cW~Uv|eB&yYwAObSwL2vY~UYI7NXPvf3b+c^?wcs~_t{ ze_m66-0)^{JdOMKPwjpQ@Sna!*?$wTZ~su*tNv7o!gXT!GRgivP}ec?5>l1!7<(rT zds|8x(qGc673zrvYIz;J23FG{9nHMnAuP}NpAED^laz3mAN1sy+NXK)!6v1FxQ;lh zOBLA>$~P3r4b*NcqR;y6pwyhZ3_PiDb|%n1gGjl3ZU}ujInlP{eks-#oA6>rh&g+!f`hv#_%JrgYPu z(U^&XLW^QX7F9Z*SRPpQl{B%x)_AMp^}_v~?j7 zapvHMKxSf*Mtyx8I}-<*UGn3)oHd(nn=)BZ`d$lDBwq_GL($_TPaS{UeevT(AJ`p0 z9%+hQb6z)U9qjbuXjg|dExCLjpS8$VKQ55VsIC%@{N5t{NsW)=hNGI`J=x97_kbz@ E0Of=7!TQj4N+cqN`nQhxvX7dAV-`K|Ub$-q+H-5I?Tx0g9jWxd@A|?POE8`3b8fO$T))xP* z(X?&brZw({`)WU&rdAs1iTa0x6F@PIxJ&&L|dpySV!ID|iUhjCcKz(@mE z!x@~W#3H<)4Ae(4eQJRk`Iz3<1)6^m)0b_4_TRZ+cz#eD3f8V;2r-1fE!F}W zEi0MEkTTx}8i1{`l_6vo0(Vuh0HD$I4SjZ=?^?k82R51bC)2D_{y8mi_?X^=U?2|F{Vr7s!k(AZC$O#ZMyavHhlQ7 zUR~QXuH~#o#>(b$u4?s~HLF*3IcF7023AlwAYudn0FV~|odGH^05AYPEfR)8p`i{n zwg3zPVp{+wOsxKc>)(pMupKF!Y2HoUqQ3|Yu|8lwR=?5zZuhG6J?H`bSNk_wPoM{u zSL{c@pY7+c2kck>`^q1^^gR0QB7Y?KUD{vz-uVX~;V-rW)PDcI)$_UjgVV?S?=oLR zf4}zz{#*R_{LkiJ#0RdQLNC^2Vp%JPEUvG9ra2BVZ92(p9h7Ka@!yf9(lj#}>+|u* z;^_?KWdzkM`6gqPo9;;r6&JEa)}R3X{(CWv?NvgLeOTq$cZXqf7|sPImi-7cS8DCN zGf;DVt3Am`>hH3{4-WzH43Ftx)SofNe^-#|0HdCo<+8Qs!}TZP{HH8~z5n`ExcHuT zDL1m&|DVpIy=xsLO>8k92HcmfSKhflQ0H~9=^-{#!I1g(;+44xw~=* zxvNz35vfsQE)@)Zsp*6_GjYD};Squ83<_?^SbALb{a`j<0Gn%6JY!zhp=Fg}Ga2|8 z52e1WU%^L1}15Ex0fF$e@eCT(()_P zvV?CA%#Sy08_U6VPt4EtmVQraWJX` zh=N|WQ>LgrvF~R&qOfB$!%D3cGv?;Xh_z$z7k&s4N)$WYf*k=|*jCEkO19{h_(%W4 zPuOqbCw`SeAX*R}UUsbVsgtuG?xs(#Ikx9`JZoQFz0n*7ZG@Fv@kZk`gzO$HoA9kN z8U5{-yY zvV{`&WKU2$mZeoBmiJrEdzUZAv1sRxpePdg1)F*X^Y)zp^Y*R;;z~vOv-z&)&G)JQ{m!C9cmziu1^nHA z`#`0c>@PnQ9CJKgC5NjJD8HM3|KC(g5nnCq$n0Gsu_DXk36@ql%npEye|?%RmG)

FJ$wK}0tWNB{uH;AM~i literal 0 HcmV?d00001 diff --git a/example/app-test/android/src/main/res/mipmap-xhdpi/ic_launcher.webp b/example/app-test/android/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..948a3070fe34c611c42c0d3ad3013a0dce358be0 GIT binary patch literal 1900 zcmV-y2b1_xNk&Fw2LJ$9MM6+kP&il$0000G0001A003VA06|PpNH75a00DqwTbm-~ zullQTcXxO9ki!OCRx^i?oR|n!<8G0=kI^!JSjFi-LL*`V;ET0H2IXfU0*i>o6o6Gy zRq6Ap5(_{XLdXcL-MzlN`ugSdZY_`jXhcENAu)N_0?GhF))9R;E`!bo9p?g?SRgw_ zEXHhFG$0{qYOqhdX<(wE4N@es3VIo$%il%6xP9gjiBri+2pI6aY4 zJbgh-Ud|V%3O!IcHKQx1FQH(_*TK;1>FQWbt^$K1zNn^cczkBs=QHCYZ8b&l!UV{K z{L0$KCf_&KR^}&2Fe|L&?1I7~pBENnCtCuH3sjcx6$c zwqkNkru);ie``q+_QI;IYLD9OV0ZxkuyBz|5<$1BH|vtey$> z5oto4=l-R-Aaq`Dk0}o9N0VrkqW_#;!u{!bJLDq%0092{Ghe=F;(kn} z+sQ@1=UlX30+2nWjkL$B^b!H2^QYO@iFc0{(-~yXj2TWz?VG{v`Jg zg}WyYnwGgn>{HFaG7E~pt=)sOO}*yd(UU-D(E&x{xKEl6OcU?pl)K%#U$dn1mDF19 zSw@l8G!GNFB3c3VVK0?uyqN&utT-D5%NM4g-3@Sii9tSXKtwce~uF zS&Jn746EW^wV~8zdQ1XC28~kXu8+Yo9p!<8h&(Q({J*4DBglPdpe4M_mD8AguZFn~ ztiuO~{6Bx?SfO~_ZV(GIboeR9~hAym{{fV|VM=77MxDrbW6`ujX z<3HF(>Zr;#*uCvC*bpoSr~C$h?_%nXps@A)=l_;({Fo#6Y1+Zv`!T5HB+)#^-Ud_; zBwftPN=d8Vx)*O1Mj+0oO=mZ+NVH*ptNDC-&zZ7Hwho6UQ#l-yNvc0Cm+2$$6YUk2D2t#vdZX-u3>-Be1u9gtTBiMB^xwWQ_rgvGpZ6(C@e23c!^K=>ai-Rqu zhqT`ZQof;9Bu!AD(i^PCbYV%yha9zuoKMp`U^z;3!+&d@Hud&_iy!O-$b9ZLcSRh? z)R|826w}TU!J#X6P%@Zh=La$I6zXa#h!B;{qfug}O%z@K{EZECu6zl)7CiNi%xti0 zB{OKfAj83~iJvmpTU|&q1^?^cIMn2RQ?jeSB95l}{DrEPTW{_gmU_pqTc)h@4T>~& zluq3)GM=xa(#^VU5}@FNqpc$?#SbVsX!~RH*5p0p@w z;~v{QMX0^bFT1!cXGM8K9FP+=9~-d~#TK#ZE{4umGT=;dfvWi?rYj;^l_Zxywze`W z^Cr{55U@*BalS}K%Czii_80e0#0#Zkhlij4-~I@}`-JFJ7$5{>LnoJSs??J8kWVl6|8A}RCGAu9^rAsfCE=2}tHwl93t0C?#+jMpvr7O3`2=tr{Hg$=HlnjVG^ewm|Js0J*kfPa6*GhtB>`fN!m#9J(sU!?(OSfzY*zS(FJ<-Vb zfAIg+`U)YaXv#sY(c--|X zEB+TVyZ%Ie4L$gi#Fc++`h6%vzsS$pjz9aLt+ZL(g;n$Dzy5=m=_TV(3H8^C{r0xd zp#a%}ht55dOq?yhwYPrtp-m1xXp;4X;)NhxxUpgP%XTLmO zcjaFva^}dP3$&sfFTIR_jC=2pHh9kpI@2(6V*GQo7Ws)`j)hd+tr@P~gR*2gO@+1? zG<`_tB+LJuF|SZ9tIec;h%}}6WClT`L>HSW?E{Hp1h^+mlbf_$9zA>!ug>NALJsO{ mU%z=YwVD?}XMya)Bp;vlyE5&E_6!fzx9pwrdz474!~g(M6R?N? literal 0 HcmV?d00001 diff --git a/example/app-test/android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/example/app-test/android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..1b9a6956b3acdc11f40ce2bb3f6efbd845cc243f GIT binary patch literal 3918 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�(p-{x$&=IACIfoAR!za)F-^da-t3#0Dycnp zwO~NVXwXCl;jE<}>%@xz|=8fIJAB?>+E{7)|4l${4ngA3G|=r z2Dyv;VVWSgZx9Wj>qUjleGl3Ei9K4>h!(lPS%8VOG>Xu0%6VDz^O=bjJmuP7>DeUv zrbI}MlHB^^d?{zv6d=@_ZD2lg1&G7UjnVN{1}9WkaM3H~btX0GtSzB+tZ^qRgWo4m z!GmimlG$=wgXCnr6j@m<1gAL46#T~5Bnm=2{^@>|t&`9mkEPddj zAvG~@Tv~TAm2i%VW}R-g(Z0)z-Y|szHr@rk>4MAyG*Ma*7Yh#H7(!-5>DZ@8r;_dx z{prSe<>~099F8vsYd2xff7uAS%7{S)f(|@me3t2$iy&NEc7OUEchp@9A|X;;IA>8!oX+y(BKJ$EzV* znR$z;!L$s7uy@{OT~nG#B!NRraT8(X##Ho!0r_o@gg0CA-9H^;-uE&?$2$nHv_00o z%cbuUc-tCx$Uh&EZ4Nf4Zgqv)Y6>usG3>GeQnxx_Z6+PcbX-+ysbt1hQ`K1LDpOE? zrAhIZhSN9yVIAOa22gn577tbc&i3|3V8NWy&!tw##`}9*x}gtI^h1DzZRA>UuaJG) zaZ7j)dq!O}{?#8Y7~7i6fHh4{`pL?>-18|p!S75Y#^DM>-S3)vuZG+Q7l@ek zQP~#cBpWgg#mApc_sPYjpw8odQuRokmTkzcNl`^CcKB7e&;zViV;{Y{o^Y$%7i0m# z62%#1Lq!RC?}lK>%mp}T!3Xv;L*0v*>USLm``N%>w>@fwC+#T&Tx2bN4w(20JB}oU zuSa6v^kXi0xPs?pbaOHnyiqq6By1EZY9OZ^^QA>{q-Hsd&m`pbQ%8121aWG-F5xf zlZ%;B{;C>X19|`^_?dVyCq>n+41w7|!tUS!{9rHlbhX=SZO5CQ^;!Du_E7*`GiR^Q w)2!4MKjfSAeNo!9>IaV6aUZ*?W>} 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

UmY2RIYtNPVDpE$%vda+HD#3m z&VuXJ{BK&Qe+rBa7eq}Q(bq|tn(RrJAk|ztj2(i{d>nmQnM?;HF2k&9sA6up5tmjl z7lySlzMbifH17-m-Lwa_F&e7nOH?ESi3#ckR3tsM+jsck3`oG!uMS}|eAwVXv>}qxwq?QY%QJ0}r@^;fhuUA9W z*BVl>TGo&N004@xSiwDUXUvp51sVmqO3m)=B55aPwf@0=e}cN+$-BdKxY`YrT_4)0 z_d10#i44Q*rFr8MC>*)v$EJvz``(pb{e&*6k+b zsMz%($|1+8hn8c2?P(l@;Rb&CsZeYoCI3?2!LqjbwPXW3z4G$Qfj=cT5Yb%vY0(AX oeb?AaKtwrnc|$|zzw9vfvn^aJJ!zd)XFXqqy0000001=f@-~a#s literal 0 HcmV?d00001 diff --git a/example/app-test/android/src/main/res/values/colors.xml b/example/app-test/android/src/main/res/values/colors.xml new file mode 100644 index 00000000..f8c6127d --- /dev/null +++ b/example/app-test/android/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/example/app-test/android/src/main/res/values/strings.xml b/example/app-test/android/src/main/res/values/strings.xml new file mode 100644 index 00000000..abe3d1df --- /dev/null +++ b/example/app-test/android/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + TestLib + \ No newline at end of file diff --git a/example/app-test/core/build.gradle.kts b/example/app-test/core/build.gradle.kts new file mode 100644 index 00000000..adeffa84 --- /dev/null +++ b/example/app-test/core/build.gradle.kts @@ -0,0 +1,5 @@ +dependencies { + implementation(project(":example:lib-test:lib-core")) + + implementation("com.badlogicgames.gdx:gdx:${LibExt.gdxVersion}") +} \ No newline at end of file diff --git a/example/app-test/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTestLib.java b/example/app-test/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTestLib.java new file mode 100644 index 00000000..f1046cfa --- /dev/null +++ b/example/app-test/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTestLib.java @@ -0,0 +1,375 @@ +package com.github.xpenatan.jparser.example.app; + +import com.badlogic.gdx.ApplicationAdapter; +import com.badlogic.gdx.utils.ScreenUtils; +import lib.emscripten.TestLibLoader; +import lib.test.ArrayArgumentTest; +import lib.test.ArrayClass; +import lib.test.Child1; +import lib.test.Child2; +import lib.test.EnumClass; +import lib.test.EnumClass_EnumWithinClass; +import lib.test.Inner; +import lib.test.ObjectFactory; +import lib.test.Parent; +import lib.test.ReceiveArrays; +import lib.test.RefUser; +import lib.test.StoreArray; +import lib.test.StringUser; +import lib.test.StructInArray; +import lib.test.TypeTestClass; +import lib.test.VoidPointerUser; +import lib.test.idl.helper.IDLByteArray; +import lib.test.idl.helper.IDLIntArray; +import static lib.test.AnEnum.enum_value1; +import static lib.test.AnEnum.enum_value2; +import static lib.test.EnumNamespace_EnumInNamespace.e_namespace_val; + +public class AppTestLib extends ApplicationAdapter { + private boolean init = false; + + @Override + public void create() { + TestLibLoader.init(new Runnable() { + @Override + public void run() { + init = true; + } + }); + } + + @Override + public void render() { + ScreenUtils.clear(0.4f, 0.4f, 0.4f, 1); + if(init) { + init = false; + initLib(); + } + } + + + private void initLib() { + test(); + } + + private void test() { + Console console = new Console(); + + // Part 1 + + var sme = new Parent(42); + sme.mulVal(2); + console.log("*"); + console.log(sme.getVal()); + console.log(sme.getAsConst()); + console.log(sme.voidStar(sme.getCPointer())); + console.log(sme.get_immutableAttr()); + console.log(sme.get_immutableAttr()); + + console.log(sme.get_attr()); + sme.set_attr(9); + console.log(sme.get_attr()); + sme.set_attr(10); + console.log(sme.get_attr()); + + console.log(sme.getBoolean()); + + console.log("c1"); +// + var c1 = new Child1(); + console.log(c1.getVal()); + c1.mulVal(2); + console.log(c1.getVal()); + console.log(c1.getValSqr()); + console.log(c1.getValSqr(3)); +// console.log(c1.getValTimes()); // default argument should be 1 +// console.log(c1.getValTimes(2)); + console.log(sme.getBoolean()); + c1.parentFunc(90); + + console.log("c1 v2"); +// + c1 = new Child1(8); // now with a parameter, we should handle the overloading automatically and properly and use constructor #2 + console.log(c1.getVal()); + c1.mulVal(2); + console.log(c1.getVal()); + console.log(c1.getValSqr()); + console.log(c1.getValSqr(3)); + console.log(sme.getBoolean()); + + console.log("c2"); + + int succeeded = 0; + + var c2 = new Child2(); + console.log(c2.getVal()); + c2.mulVal(2); + console.log(c2.getVal()); + console.log(c2.getValCube()); + try { + succeeded = 0; + c2.getValCube(); // sanity + succeeded = 1; + } catch(Throwable t) {} + console.log(succeeded); + + Child2.printStatic(42); // static calls go through the prototype + + // virtual function +// c2.virtualFunc(); +// Child2.runVirtualFunc(c2); +// c2.virtualFunc2(); + + // extend a class from JS +// var c3 = new TheModule.Child2JS; +// +// c3.virtualFunc = function() { +// console.log('*js virtualf replacement*'); +// }; +// c3.virtualFunc2 = function() { +// console.log('*js virtualf2 replacement*'); +// }; +// c3.virtualFunc3 = function(x) { +// console.log('*js virtualf3 replacement ' + x + '*'); +// }; +// +// c3.virtualFunc(); +// TheModule.Child2.prototype.runVirtualFunc(c3); +// c3.virtualFunc2(); +// c3.virtualFunc3(123); // this one is not replaced! +// try { +// c3.virtualFunc4(123); +// } catch(e) { +// console.log('caught: ' + e); +// } +// + // Test virtual method dispatch from c++ +// Child2.runVirtualFunc3(c3, 43); +// +// c2.virtualFunc(); // original should remain the same +// Child2.runVirtualFunc(c2); +// c2.virtualFunc2(); +// console.log("*ok*"); + + // Part 2 + + var suser = new StringUser("hello", 43); + suser.Print(41, "world"); + suser.PrintFloat(12.3456f); +// console.log(suser.returnAString()); + + var bv = new RefUser(10); + var bv2 = new RefUser(11); + console.log(bv2.getValue(bv)); + + console.log(bv2.getMe().getClass()); + console.log(bv2.getMe().getValue(bv)); + console.log(bv2.getMe().getValue(bv2)); + + console.log(bv2.getCopy().getClass()); + console.log(bv2.getCopy().getValue(bv)); + console.log(bv2.getCopy().getValue(bv2)); + + bv2.getAnother().PrintFloat(21.12f); + + console.log(new Inner().get()); +// console.log('getAsArray: ' + new Inner().getAsArray(12)); +// new Inner().mul(2); +// new Inner().incInPlace(new Inner()); + + console.log(enum_value1); + console.log(enum_value2); + + // Enums from classes are accessed via the class. + var enumClassInstance = new EnumClass(); + console.log(enumClassInstance.GetEnum()); + console.log(EnumClass_EnumWithinClass.e_val); +// console.log([enumClassInstance.GetEnum(), EnumClass.e_val].join(',')); + + // Enums from namespaces are accessed via the top-level module, as with classes defined + // in namespaces, see `Inner` above. + console.log(e_namespace_val); + + var typeTester = new TypeTestClass(); + + console.log("return char " + (typeTester.ReturnCharMethod() & 255)); + typeTester.AcceptCharMethod((byte)((2<<6)-1)); + typeTester.AcceptCharMethod((byte)-1); + +// console.log("return unsigned char " + (typeTester.ReturnUnsignedCharMethod() & 255)); +// typeTester.AcceptUnsignedCharMethod((2<<7)-1); + + console.log("return unsigned short " + (typeTester.ReturnUnsignedShortMethod() & 65535)); + typeTester.AcceptUnsignedShortMethod((short)((2<<15)-1)); + + console.log("return unsigned long " + (typeTester.ReturnUnsignedLongMethod() | 0)); + typeTester.AcceptUnsignedLongMethod((2<<31)-1); + var voidPointerUser = new VoidPointerUser(); + + voidPointerUser.SetVoidPointer(3); + console.log("void * " + voidPointerUser.GetVoidPointer()); + + // Array tests + + var arrayClass = new ArrayClass(); +// console.log("int_array[0] == " + arrayClass.get_int_array(0)); +// console.log("int_array[7] == " + arrayClass.get_int_array(7)); +// arrayClass.set_int_array(0, 42); +// arrayClass.set_int_array(7, 43); +// console.log("int_array[0] == " + arrayClass.get_int_array(0)); +// console.log("int_array[7] == " + arrayClass.get_int_array(7)); + +// try { +// arrayClass.set_int_array(-1, 42); +// } catch (Throwable e) { +// console.log("idx -1: " + e); +// } + +// try { +// arrayClass.set_int_array(8, 42); +// } catch (Throwable e) { +// console.log("idx 8: " + e); +// } +// +// console.log("struct_array[0].attr1 == " + arrayClass.get_struct_array(0).get_attr1()); +// console.log("struct_array[0].attr2 == " + arrayClass.get_struct_array(0).get_attr2()); +// console.log("struct_array[7].attr1 == " + arrayClass.get_struct_array(7).get_attr1()); +// console.log("struct_array[7].attr2 == " + arrayClass.get_struct_array(7).get_attr2()); + + // Verify that bounds checking is *not* enabled when not asked for. + // This actually causes an illegal memory access, but as it's only a read, and the return + // value is not used, it shouldn't cause any problems in practice. +// arrayClass.get_struct_array(8); +// + var struct = new StructInArray(13, 17); +// arrayClass.set_struct_array(0, struct); + struct = new StructInArray(14, 18); +// arrayClass.set_struct_array(7, struct); + +// console.log("struct_array[0].attr1 == " + arrayClass.get_struct_array(0).get_attr1()); +// console.log("struct_array[0].attr2 == " + arrayClass.get_struct_array(0).get_attr2()); +// console.log("struct_array[7].attr1 == " + arrayClass.get_struct_array(7).get_attr1()); +// console.log("struct_array[7].attr2 == " + arrayClass.get_struct_array(7).get_attr2()); +// + struct = new StructInArray(100, 101); +// arrayClass.set_struct_ptr_array(0, struct); +// console.log("struct_ptr_array[0]->attr1 == " + arrayClass.get_struct_ptr_array(0).get_attr1()); +// console.log("struct_ptr_array[0]->attr2 == " + arrayClass.get_struct_ptr_array(0).get_attr2()); + + // receiving arrays + + var receiver = new ReceiveArrays(); +// receiver.giveMeArrays([0.5, 0.25, 0.01, -20.42], [1, 4, 9, 10], 4); + + // Test IDL_CHECKS=ALL + +// try { +// p = new Parent(NaN); // Expects an integer +// } catch (e) {} + + try { + Parent p = new Parent(42); + p.voidStar(1234); // Expects a wrapped pointer + } catch (Throwable e) {} + + try { + StringUser s = new StringUser("abc", 1); + s.Print(123, null); // Expects a string or a wrapped pointer + } catch (Throwable e) {} + + // Returned pointers (issue 14745) + + var factory = new ObjectFactory(); + var objectProvider = factory.getProvider(); + var smallObject = objectProvider.getObject(); + + // This will print 123 if we managed to access the object, which means that integers + // were correctly typecast to ObjectProvider pointer and SmallObject pointer. + console.log(smallObject.getID(123)); + + factory.dispose(); + + // end of issue 14745 + + // octet[] to char* (issue 14827) + + var arrayTestObj = new ArrayArgumentTest(); + var bufferAddr = new IDLByteArray(35); +// TheModule.stringToUTF8('I should match the member variable', bufferAddr, 35); + + var arrayTestResult = arrayTestObj.byteArrayTest(bufferAddr); + var arrayDomStringResult = arrayTestObj.domStringTest("I should match the member variable"); + console.log(arrayTestResult); + console.log(arrayDomStringResult); + + arrayTestObj.dispose(); + + bufferAddr.dispose(); + // end of issue 14827 + + // Check for overflowing the stack + +// var before = Date.now(); +// +// for (var i = 0; i < 1000000; i++) { +// var temp = new TheModule.StringUser('abc', 1); +// TheModule.destroy(temp); +// if (Date.now() - before >= 1000) break; +// } + + boolean isMemoryGrowthAllowed = true; + if(isMemoryGrowthAllowed) { + // Check for HEAP reallocation when using large arrays + var numArrayEntries = 100000; + var intArray = new IDLIntArray(numArrayEntries); + for (var i = 0; i < numArrayEntries; i++) { + intArray.setValue(i, i); + } + +// var startHeapLength = TheModule['HEAP8'].length; + int offset; + var storeArray = new StoreArray(); + storeArray.setArray(intArray); + // Add more data until the heap is reallocated +// while (TheModule['HEAP8'].length === startHeapLength) { +// intArray = intArray.concat(intArray); +// storeArray.setArray(intArray); +// } +// +// // Make sure the array was copied to the newly allocated HEAP +// var numCopiedEntries = 0; +// for (var i = 0; i < intArray.length; i++) { +// if (storeArray.getArrayValue(i) !== intArray[i]) { +// break; +// } +// numCopiedEntries += 1; +// } +// +// if (intArray.length !== numCopiedEntries) { +// console.log('ERROR: An array was not copied to HEAP32 after memory reallocation'); +// } + } + console.log("\ndone."); + } + + static class Console { + public void log(Object text) { + System.out.println(text); + } + public void log(Class text) { + System.out.println(text); + } + public void log(int text) { + System.out.println(text); + } + public void log(float text) { + System.out.println(text); + } + public void log(boolean text) { + System.out.println(text); + } + public void log(String text) { + System.out.println(text); + } + } +} \ No newline at end of file diff --git a/example/app-test/desktop/assets/data/badlogic.jpg b/example/app-test/desktop/assets/data/badlogic.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4390da6e0f6d041590c6313d2b4c978abc00a342 GIT binary patch literal 68465 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%0D_mtl(=kJ_v@+V;1Dd59><)1Vxf({Tq^pY-s)84 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 literal 0 HcmV?d00001 diff --git a/example/app-test/desktop/build.gradle.kts b/example/app-test/desktop/build.gradle.kts new file mode 100644 index 00000000..d9a014c6 --- /dev/null +++ b/example/app-test/desktop/build.gradle.kts @@ -0,0 +1,22 @@ +import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform + +dependencies { + implementation(project(":example:app-test:core")) + implementation(project(":example:lib-test:lib-desktop")) + + implementation("com.badlogicgames.gdx:gdx-platform:${LibExt.gdxVersion}:natives-desktop") + implementation("com.badlogicgames.gdx:gdx-backend-lwjgl3:${LibExt.gdxVersion}") +} + +val mainClassName = "com.github.xpenatan.jparser.example.app.Main" + +tasks.register("run-app-desktop") { + group = "example-desktop" + description = "Run desktop app" + mainClass.set(mainClassName) + classpath = sourceSets["main"].runtimeClasspath + + if(DefaultNativePlatform.getCurrentOperatingSystem().isMacOsX) { + jvmArgs("-XstartOnFirstThread") + } +} \ No newline at end of file diff --git a/example/app-test/desktop/src/main/java/com/github/xpenatan/jparser/example/app/Main.java b/example/app-test/desktop/src/main/java/com/github/xpenatan/jparser/example/app/Main.java new file mode 100644 index 00000000..55da9100 --- /dev/null +++ b/example/app-test/desktop/src/main/java/com/github/xpenatan/jparser/example/app/Main.java @@ -0,0 +1,12 @@ +package com.github.xpenatan.jparser.example.app; + +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application; +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration; + +public class Main { + + public static void main(String[] args) { + Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration(); + new Lwjgl3Application(new AppTestLib(), config); + } +} \ No newline at end of file diff --git a/example/app-test/teavm/build.gradle.kts b/example/app-test/teavm/build.gradle.kts new file mode 100644 index 00000000..53adc2bc --- /dev/null +++ b/example/app-test/teavm/build.gradle.kts @@ -0,0 +1,34 @@ +plugins { + id("org.gretty") version("3.1.0") +} + +gretty { + contextPath = "/" + extraResourceBase("build/dist/webapp") +} + +dependencies { + implementation(project(":example:app-test:core")) + implementation(project(":example:lib-test:lib-teavm")) + + implementation("com.badlogicgames.gdx:gdx:${LibExt.gdxVersion}") + implementation("com.github.xpenatan.gdx-teavm:backend-teavm:${LibExt.gdxTeaVMVersion}") +} + +val mainClassName = "Build" + +tasks.register("build-app-teavm") { + group = "example-teavm" + description = "Build teavm app" + mainClass.set(mainClassName) + classpath = sourceSets["main"].runtimeClasspath +} + +tasks.register("run-app-teavm") { + group = "example-teavm" + description = "Run teavm app" + val list = listOf("build-app-teavm", "jettyRun") + dependsOn(list) + + tasks.findByName("jettyRun")?.mustRunAfter("build-app-teavm") +} \ No newline at end of file diff --git a/example/app-test/teavm/src/main/java/Build.java b/example/app-test/teavm/src/main/java/Build.java new file mode 100644 index 00000000..3a9351bd --- /dev/null +++ b/example/app-test/teavm/src/main/java/Build.java @@ -0,0 +1,21 @@ +import com.github.xpenatan.gdx.backends.teavm.config.AssetFileHandle; +import com.github.xpenatan.gdx.backends.teavm.config.TeaBuildConfiguration; +import com.github.xpenatan.gdx.backends.teavm.config.TeaBuilder; +import com.github.xpenatan.gdx.backends.teavm.gen.SkipClass; +import java.io.File; +import java.io.IOException; +import org.teavm.tooling.TeaVMTool; + +@SkipClass +public class Build { + + public static void main(String[] args) throws IOException { + TeaBuildConfiguration teaBuildConfiguration = new TeaBuildConfiguration(); + teaBuildConfiguration.assetsPath.add(new AssetFileHandle("../desktop/assets")); + teaBuildConfiguration.webappPath = new File("build/dist").getCanonicalPath(); + TeaVMTool tool = TeaBuilder.config(teaBuildConfiguration); + tool.setMainClass(TeaVMLauncher.class.getName()); + tool.setObfuscated(false); + TeaBuilder.build(tool); + } +} diff --git a/example/app-test/teavm/src/main/java/TeaVMLauncher.java b/example/app-test/teavm/src/main/java/TeaVMLauncher.java new file mode 100644 index 00000000..1317b728 --- /dev/null +++ b/example/app-test/teavm/src/main/java/TeaVMLauncher.java @@ -0,0 +1,13 @@ +import com.github.xpenatan.gdx.backends.teavm.TeaApplication; +import com.github.xpenatan.gdx.backends.teavm.TeaApplicationConfiguration; +import com.github.xpenatan.jparser.example.app.AppTestLib; + +public class TeaVMLauncher { + public static void main(String[] args) { + TeaApplicationConfiguration config = new TeaApplicationConfiguration("canvas"); + config.width = 0; + config.height = 0; + config.showDownloadLogs = true; + new TeaApplication(new AppTestLib(), config); + } +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 1bfdbf6f..103d305e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -32,6 +32,11 @@ include(":example:app:desktop") include(":example:app:teavm") include(":example:app:android") +include(":example:app-test:core") +include(":example:app-test:desktop") +include(":example:app-test:teavm") +include(":example:app-test:android") + //includeBuild("E:\\Dev\\Projects\\java\\gdx-teavm") { // dependencySubstitution { From e5ca25c8d3cbf2047e01c125a84812b753f845d9 Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 10 Aug 2024 21:28:02 -0300 Subject: [PATCH 043/186] add string data method --- .../src/main/java/idl/helper/IDLString.java | 18 ++++++++++++++++++ jParser/base/src/main/resources/IDLHelper.idl | 1 + 2 files changed, 19 insertions(+) diff --git a/jParser/base/src/main/java/idl/helper/IDLString.java b/jParser/base/src/main/java/idl/helper/IDLString.java index b72f085a..e8bc0f51 100644 --- a/jParser/base/src/main/java/idl/helper/IDLString.java +++ b/jParser/base/src/main/java/idl/helper/IDLString.java @@ -36,4 +36,22 @@ public String c_str() { return returnedJSObj; */ private static native String c_strNATIVE(long this_addr); + + public String data() { + String text = dataNATIVE(getCPointer()); + return text; + } + + /*[-JNI;-NATIVE] + IDLString* nativeObject = (IDLString*)this_addr; + const char* str = nativeObject->data(); + jstring jstrBuf = env->NewStringUTF(str); + return jstrBuf; + */ + /*[-TEAVM;-NATIVE] + var jsObj = [MODULE].wrapPointer(this_addr, [MODULE].IDLString); + var returnedJSObj = jsObj.data(); + return returnedJSObj; + */ + private static native String dataNATIVE(long this_addr); } \ No newline at end of file diff --git a/jParser/base/src/main/resources/IDLHelper.idl b/jParser/base/src/main/resources/IDLHelper.idl index a2bda44e..96ba416e 100644 --- a/jParser/base/src/main/resources/IDLHelper.idl +++ b/jParser/base/src/main/resources/IDLHelper.idl @@ -6,6 +6,7 @@ interface IDLString { void append([Const] DOMString text, long size); long size(); byte at(long index); + [Const] DOMString data(); [Const] DOMString c_str(); }; From fe1d4381f4421f78f7fbc6990883e82c01876b8d Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 10 Aug 2024 21:32:39 -0300 Subject: [PATCH 044/186] add IDLStringView --- .../main/java/idl/helper/IDLStringView.java | 39 +++++++++++++++++++ jParser/base/src/main/resources/IDLHelper.h | 1 + jParser/base/src/main/resources/IDLHelper.idl | 8 ++++ 3 files changed, 48 insertions(+) create mode 100644 jParser/base/src/main/java/idl/helper/IDLStringView.java diff --git a/jParser/base/src/main/java/idl/helper/IDLStringView.java b/jParser/base/src/main/java/idl/helper/IDLStringView.java new file mode 100644 index 00000000..66144a96 --- /dev/null +++ b/jParser/base/src/main/java/idl/helper/IDLStringView.java @@ -0,0 +1,39 @@ +package idl.helper; + +import idl.IDLBase; + +public class IDLStringView extends IDLBase { + + public static IDLStringView TMP_EMPTY_1 = new IDLStringView((byte)0, '0'); + + public static IDLStringView TMP_1 = new IDLStringView(); + public static IDLStringView TMP_2 = new IDLStringView(); + + public static void disposeTEMP() { + TMP_1.dispose(); + TMP_2.dispose(); + } + + public IDLStringView() { + } + + public IDLStringView(byte b, char c) {} + + public String data() { + String text = dataNATIVE(getCPointer()); + return text; + } + + /*[-JNI;-NATIVE] + IDLStringView* nativeObject = (IDLStringView*)this_addr; + const char* str = nativeObject->data(); + jstring jstrBuf = env->NewStringUTF(str); + return jstrBuf; + */ + /*[-TEAVM;-NATIVE] + var jsObj = [MODULE].wrapPointer(this_addr, [MODULE].IDLStringView); + var returnedJSObj = jsObj.data(); + return returnedJSObj; + */ + private static native String dataNATIVE(long this_addr); +} \ No newline at end of file diff --git a/jParser/base/src/main/resources/IDLHelper.h b/jParser/base/src/main/resources/IDLHelper.h index c8c3617a..db54303e 100644 --- a/jParser/base/src/main/resources/IDLHelper.h +++ b/jParser/base/src/main/resources/IDLHelper.h @@ -5,6 +5,7 @@ #include // intptr_t typedef std::string IDLString; +typedef std::string_view IDLStringView; class IDLBoolArray { private: diff --git a/jParser/base/src/main/resources/IDLHelper.idl b/jParser/base/src/main/resources/IDLHelper.idl index 96ba416e..c3fdfa21 100644 --- a/jParser/base/src/main/resources/IDLHelper.idl +++ b/jParser/base/src/main/resources/IDLHelper.idl @@ -10,6 +10,14 @@ interface IDLString { [Const] DOMString c_str(); }; +interface IDLStringView { + void IDLStringView([Const] DOMString text); + void IDLStringView([Const] DOMString text, long size); + long size(); + byte at(long index); + [Const] DOMString data(); +}; + interface IDLBoolArray { void IDLBoolArray(long size); void resize(long size); From 01059460bdaef99a0097ac66cac43712b484fc68 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 11 Aug 2024 12:02:56 -0300 Subject: [PATCH 045/186] Add template array and some improvements --- ...app-test_desktop [run-app-desktop].run.xml | 24 +++ ...mple_app_desktop [run-app-desktop].run.xml | 24 +++ ..._example_app_teavm [run-app-teavm].run.xml | 24 +++ ...test_lib-build [build_project_all].run.xml | 24 +++ ..._lib_lib-build [build_project_all].run.xml | 24 +++ .../jparser/example/app/AppTestLib.java | 2 +- .../{emscripten => test}/TestLibLoader.java | 2 +- .../lib/lib-build/src/main/cpp/exampleLib.idl | 3 +- jParser/base/src/main/resources/IDLHelper.h | 147 ++++-------------- jParser/base/src/main/resources/IDLHelper.idl | 20 ++- .../xpenatan/jparser/cpp/CppCodeParser.java | 8 +- .../idl/parser/IDLAttributeParser.java | 2 +- .../idl/parser/IDLConstructorParser.java | 2 +- .../jparser/idl/parser/IDLMethodParser.java | 33 ++-- 14 files changed, 190 insertions(+), 149 deletions(-) create mode 100644 .run/jParser_example_app-test_desktop [run-app-desktop].run.xml create mode 100644 .run/jParser_example_app_desktop [run-app-desktop].run.xml create mode 100644 .run/jParser_example_app_teavm [run-app-teavm].run.xml create mode 100644 .run/jParser_example_lib-test_lib-build [build_project_all].run.xml create mode 100644 .run/jParser_example_lib_lib-build [build_project_all].run.xml rename example/lib-test/lib-base/src/main/java/lib/{emscripten => test}/TestLibLoader.java (98%) diff --git a/.run/jParser_example_app-test_desktop [run-app-desktop].run.xml b/.run/jParser_example_app-test_desktop [run-app-desktop].run.xml new file mode 100644 index 00000000..19a44750 --- /dev/null +++ b/.run/jParser_example_app-test_desktop [run-app-desktop].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/jParser_example_app_desktop [run-app-desktop].run.xml b/.run/jParser_example_app_desktop [run-app-desktop].run.xml new file mode 100644 index 00000000..57fc755d --- /dev/null +++ b/.run/jParser_example_app_desktop [run-app-desktop].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/jParser_example_app_teavm [run-app-teavm].run.xml b/.run/jParser_example_app_teavm [run-app-teavm].run.xml new file mode 100644 index 00000000..6a3559ae --- /dev/null +++ b/.run/jParser_example_app_teavm [run-app-teavm].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/jParser_example_lib-test_lib-build [build_project_all].run.xml b/.run/jParser_example_lib-test_lib-build [build_project_all].run.xml new file mode 100644 index 00000000..e47fc935 --- /dev/null +++ b/.run/jParser_example_lib-test_lib-build [build_project_all].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/jParser_example_lib_lib-build [build_project_all].run.xml b/.run/jParser_example_lib_lib-build [build_project_all].run.xml new file mode 100644 index 00000000..ed10b5e4 --- /dev/null +++ b/.run/jParser_example_lib_lib-build [build_project_all].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/example/app-test/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTestLib.java b/example/app-test/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTestLib.java index f1046cfa..b74d0ccf 100644 --- a/example/app-test/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTestLib.java +++ b/example/app-test/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTestLib.java @@ -2,7 +2,6 @@ import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.utils.ScreenUtils; -import lib.emscripten.TestLibLoader; import lib.test.ArrayArgumentTest; import lib.test.ArrayClass; import lib.test.Child1; @@ -17,6 +16,7 @@ import lib.test.StoreArray; import lib.test.StringUser; import lib.test.StructInArray; +import lib.test.TestLibLoader; import lib.test.TypeTestClass; import lib.test.VoidPointerUser; import lib.test.idl.helper.IDLByteArray; diff --git a/example/lib-test/lib-base/src/main/java/lib/emscripten/TestLibLoader.java b/example/lib-test/lib-base/src/main/java/lib/test/TestLibLoader.java similarity index 98% rename from example/lib-test/lib-base/src/main/java/lib/emscripten/TestLibLoader.java rename to example/lib-test/lib-base/src/main/java/lib/test/TestLibLoader.java index 2094a3c4..6ddda5dd 100644 --- a/example/lib-test/lib-base/src/main/java/lib/emscripten/TestLibLoader.java +++ b/example/lib-test/lib-base/src/main/java/lib/test/TestLibLoader.java @@ -1,4 +1,4 @@ -package lib.emscripten; +package lib.test; import com.github.xpenatan.jparser.loader.JParserLibraryLoader; diff --git a/example/lib/lib-build/src/main/cpp/exampleLib.idl b/example/lib/lib-build/src/main/cpp/exampleLib.idl index bd40c5f0..b6affe2a 100644 --- a/example/lib/lib-build/src/main/cpp/exampleLib.idl +++ b/example/lib/lib-build/src/main/cpp/exampleLib.idl @@ -125,6 +125,5 @@ enum EnumClassWithinClass { }; enum EnumInNamespace { -// [-NAMESPACE] - "EnumNamespace::e_namespace_val" + "EnumInNamespace::e_namespace_val" }; \ No newline at end of file diff --git a/jParser/base/src/main/resources/IDLHelper.h b/jParser/base/src/main/resources/IDLHelper.h index db54303e..aa1f43b1 100644 --- a/jParser/base/src/main/resources/IDLHelper.h +++ b/jParser/base/src/main/resources/IDLHelper.h @@ -1,52 +1,25 @@ #pragma once #include +#include #include // NULL #include // intptr_t -typedef std::string IDLString; -typedef std::string_view IDLStringView; - -class IDLBoolArray { +template +class IDLArray { private: int size; - public: - bool * data; - IDLBoolArray(int size) { data = NULL; resize(size); } - ~IDLBoolArray() { if(data != NULL) { deleteData(); } } - void resize(int newSize) { - if(this->data != NULL) { - deleteData(); - } - bool * newData = new bool[newSize]; - this->data = newData; - size = newSize; - clear(); - } - void clear() { - for(int i = 0; i < size; i++) { - data[i] = 0; - } - } - void deleteData() { delete data; } - bool getValue(int index) { return data[index]; } - void setValue(int index, bool value) { data[index] = value; } - intptr_t getPointer() { return (intptr_t)data; } - int getSize() { return size; } -}; + T* data; -class IDLIntArray { - private: - int size; + void deleteData() { delete[] data; data = NULL; } public: - int * data; - IDLIntArray(int size) { data = NULL; resize(size); } - ~IDLIntArray() { if(data != NULL) { deleteData(); } } + IDLArray(int size) { data = NULL; resize(size); } + ~IDLArray() { if(data != NULL) { deleteData(); } } void resize(int newSize) { if(this->data != NULL) { deleteData(); } - int * newData = new int[newSize]; + T * newData = new T[newSize]; this->data = newData; size = newSize; clear(); @@ -56,93 +29,29 @@ class IDLIntArray { data[i] = 0; } } - void deleteData() { delete data; } - int getValue(int index) { return data[index]; } - void setValue(int index, int value) { data[index] = value; } - intptr_t getPointer() { return (intptr_t)data; } - int getSize() { return size; } -}; - -class IDLFloatArray { - private: - int size; - public: - float * data; - IDLFloatArray(int size) { data = NULL; resize(size); } - ~IDLFloatArray() { if(data != NULL) { deleteData(); } } - void resize(int newSize) { - if(this->data != NULL) { - deleteData(); - } - float * newData = new float[newSize]; - this->data = newData; - size = newSize; - clear(); - } - void clear() { - for(int i = 0; i < size; i++) { - data[i] = 0; + void copy(IDLArray& src, int srcPos, int destPos, int length) { + T* dest = data; + int srcP = srcPos; + int destP = destPos; + int count = 0; + while(count < length) { + T srcByte = src.getValue(srcP); + srcP++; + dest[destP] = srcByte; + destP++; + count++; } } - void deleteData() { delete data; } - float getValue(int index) { return data[index]; } - void setValue(int index, float value) { data[index] = value; } - intptr_t getPointer() { return (intptr_t)data; } + T getValue(int index) { return data[index]; } + void setValue(int index, T value) { data[index] = value; } int getSize() { return size; } -}; - -class IDLDoubleArray { - private: - int size; - public: - double * data; - IDLDoubleArray(int size) { data = NULL; resize(size); } - ~IDLDoubleArray() { if(data != NULL) { deleteData(); } } - void resize(int newSize) { - if(this->data != NULL) { - deleteData(); - } - double * newData = new double[newSize]; - this->data = newData; - size = newSize; - clear(); - } - void clear() { - for(int i = 0; i < size; i++) { - data[i] = 0; - } - } - void deleteData() { delete data; } - double getValue(int index) { return data[index]; } - void setValue(int index, double value) { data[index] = value; } intptr_t getPointer() { return (intptr_t)data; } - int getSize() { return size; } }; -class IDLByteArray { - private: - int size; - public: - char * data; - IDLByteArray(int size) { data = NULL; resize(size); } - ~IDLByteArray() { if(data != NULL) { deleteData(); } } - void resize(int newSize) { - if(this->data != NULL) { - deleteData(); - } - char * newData = new char[newSize]; - this->data = newData; - size = newSize; - clear(); - } - void clear() { - for(int i = 0; i < size; i++) { - data[i] = 0; - } - } - void deleteData() { delete data; } - char getValue(int index) { return data[index]; } - void setValue(int index, char value) { data[index] = value; } - intptr_t getPointer() { return (intptr_t)data; } - int getSize() { return size; } -}; \ No newline at end of file +typedef std::string IDLString; +typedef std::string_view IDLStringView; +typedef IDLArray IDLBoolArray; +typedef IDLArray IDLIntArray; +typedef IDLArray IDLFloatArray; +typedef IDLArray IDLDoubleArray; +typedef IDLArray IDLByteArray; \ No newline at end of file diff --git a/jParser/base/src/main/resources/IDLHelper.idl b/jParser/base/src/main/resources/IDLHelper.idl index c3fdfa21..a0676faf 100644 --- a/jParser/base/src/main/resources/IDLHelper.idl +++ b/jParser/base/src/main/resources/IDLHelper.idl @@ -21,44 +21,54 @@ interface IDLStringView { interface IDLBoolArray { void IDLBoolArray(long size); void resize(long size); + void clear(); boolean getValue(long index); void setValue(long index, boolean value); - long getPointer(); long getSize(); + long getPointer(); + void copy([Ref] IDLBoolArray src, long srcOffset, long destOffset, long length); }; interface IDLIntArray { void IDLIntArray(long size); void resize(long size); + void clear(); long getValue(long index); void setValue(long index, long value); - long getPointer(); long getSize(); + long getPointer(); + void copy([Ref] IDLIntArray src, long srcOffset, long destOffset, long length); }; interface IDLFloatArray { void IDLFloatArray(long size); void resize(long size); + void clear(); float getValue(long index); void setValue(long index, float value); - long getPointer(); long getSize(); + long getPointer(); + void copy([Ref] IDLFloatArray src, long srcOffset, long destOffset, long length); }; interface IDLDoubleArray { void IDLDoubleArray(long size); void resize(long size); + void clear(); double getValue(long index); void setValue(long index, double value); - long getPointer(); long getSize(); + long getPointer(); + void copy([Ref] IDLDoubleArray src, long srcOffset, long destOffset, long length); }; interface IDLByteArray { void IDLByteArray(long size); void resize(long size); + void clear(); byte getValue(long index); void setValue(long index, byte value); - long getPointer(); long getSize(); + long getPointer(); + void copy([Ref] IDLByteArray src, long srcOffset, long destOffset, long length); }; \ No newline at end of file diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index 088b5fdf..0b8fc264 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -417,8 +417,7 @@ private static String getParams(NodeList parameters, ArrayList 0) { param += ", "; } @@ -427,12 +426,13 @@ private static String getParams(NodeList parameters, ArrayList idlParameters) { MethodDeclaration nativeMethodDeclaration = generateNativeMethod(isReturnValue, methodDeclaration, methodName); if(!JParserHelper.containsMethod(classDeclaration, nativeMethodDeclaration)) { //Add native method if it does not exist @@ -168,20 +168,20 @@ public static MethodDeclaration prepareNativeMethod(boolean isStatic, boolean is if(methodReturnType.isVoidType()) { // void types just call the method. - IDLMethodParser.setupCallerParam(isStatic, false, caller, methodDeclaration); + IDLMethodParser.setupCallerParam(isStatic, false, caller, methodDeclaration.getParameters(), idlParameters); BlockStmt blockStmt = methodDeclaration.getBody().get(); blockStmt.addStatement(caller); } else if(methodReturnType.isClassOrInterfaceType()) { // Class object needs to generate some additional code. // Needs to obtain the pointer and return a temp object. - BlockStmt blockStmt = IDLMethodParser.generateTempObjects(isReturnValue, classDeclaration, methodDeclaration, nativeMethodDeclaration, caller, operator); + BlockStmt blockStmt = IDLMethodParser.generateTempObjects(isReturnValue, classDeclaration, methodDeclaration, nativeMethodDeclaration, caller, operator, idlParameters); methodDeclaration.setBody(blockStmt); } else { // Should be a primitive return type. ReturnStmt returnStmt = IDLMethodParser.getReturnStmt(methodDeclaration); - IDLMethodParser.setupCallerParam(isStatic, false, caller, methodDeclaration); + IDLMethodParser.setupCallerParam(isStatic, false, caller, methodDeclaration.getParameters(), idlParameters); returnStmt.setExpression(caller); } return nativeMethodDeclaration; @@ -196,24 +196,27 @@ public static MethodCallExpr createCaller(MethodDeclaration nativeMethodDeclarat return caller; } - public static void setupCallerParam(boolean isStatic, boolean isReturnValue, MethodCallExpr caller, MethodDeclaration methodDeclaration) { - NodeList methodParameters = methodDeclaration.getParameters(); - setupCallerParam(isStatic, isReturnValue, caller, methodParameters); - } - - public static void setupCallerParam(boolean isStatic, boolean isReturnValue, MethodCallExpr caller, NodeList methodParameters) { + public static void setupCallerParam(boolean isStatic, boolean isReturnValue, MethodCallExpr caller, NodeList methodParameters, ArrayList idlParameters) { if(!isStatic) { caller.addArgument(IDLDefaultCodeParser.CPOINTER_METHOD); } - for(int i = 0; i < methodParameters.size(); i++) { Parameter parameter = methodParameters.get(i); + IDLParameter idlParameter = null; + if(idlParameters != null) { + idlParameter = idlParameters.get(i); + } Type type = parameter.getType(); SimpleName name = parameter.getName(); String variableName = name.getIdentifier(); String paramName = parameter.getNameAsString(); if(type.isClassOrInterfaceType()) { - if(IDLHelper.getCArray(type.asClassOrInterfaceType().getNameAsString()) != null) { + boolean isArray = true; + if(idlParameter != null) { + //TODO create IDLParameter when is comming from attribute + isArray = idlParameter.isArray; + } + if(isArray && IDLHelper.getCArray(type.asClassOrInterfaceType().getNameAsString()) != null) { String methodCall = paramName + ".getPointer()"; paramName = "(" + variableName + " != null ? " + methodCall + " : 0)"; } @@ -231,7 +234,7 @@ else if(type.isArrayType()) { } } - public static BlockStmt generateTempObjects(boolean isReturnValue, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, MethodDeclaration nativeMethodDeclaration, MethodCallExpr caller, String operator) { + private static BlockStmt generateTempObjects(boolean isReturnValue, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, MethodDeclaration nativeMethodDeclaration, MethodCallExpr caller, String operator, ArrayList idlParameters) { Type methodReturnType = methodDeclaration.getType(); String className = classDeclaration.getNameAsString(); String returnTypeName = methodReturnType.toString(); @@ -250,7 +253,7 @@ public static BlockStmt generateTempObjects(boolean isReturnValue, ClassOrInterf fieldName = generateFieldName(classDeclaration, returnTypeName, isStatic); } - IDLMethodParser.setupCallerParam(isStatic, isReturnValue, caller, methodDeclaration); + IDLMethodParser.setupCallerParam(isStatic, isReturnValue, caller, methodDeclaration.getParameters(), idlParameters); String methodCaller = caller.toString(); From 929b5361db8baba81e5bdb243ea989b6d029dc9a Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 11 Aug 2024 12:03:22 -0300 Subject: [PATCH 046/186] update indent --- example/lib/lib-build/src/main/cpp/exampleLib.idl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/lib/lib-build/src/main/cpp/exampleLib.idl b/example/lib/lib-build/src/main/cpp/exampleLib.idl index b6affe2a..7c4c2192 100644 --- a/example/lib/lib-build/src/main/cpp/exampleLib.idl +++ b/example/lib/lib-build/src/main/cpp/exampleLib.idl @@ -117,11 +117,11 @@ enum EnumTwoLib { }; enum EnumWithinClass { - "NormalClass::e_val" + "NormalClass::e_val" }; enum EnumClassWithinClass { - "EnumClassWithinClass::testEnum" + "EnumClassWithinClass::testEnum" }; enum EnumInNamespace { From b6efc205d2f9a2821e558d381ef8dea1ec7400b2 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 11 Aug 2024 22:09:19 -0300 Subject: [PATCH 047/186] Add primitive/object array attribute support --- .../xpenatan/jparser/example/app/AppTest.java | 63 +++++++++--- .../lib/lib-build/src/main/cpp/exampleLib.idl | 3 + .../cpp/source/exampleLib/src/NormalClass.h | 4 + .../xpenatan/jparser/cpp/CppCodeParser.java | 91 +++++++++++++++++ .../xpenatan/jparser/idl/IDLAttribute.java | 1 - .../idl/parser/IDLAttributeOperation.java | 98 ++++++++++++++++--- .../idl/parser/IDLAttributeParser.java | 8 ++ .../jparser/teavm/TeaVMCodeParser.java | 83 ++++++++++++++++ 8 files changed, 325 insertions(+), 26 deletions(-) diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java index a83cc0b7..332c3e27 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java @@ -32,7 +32,7 @@ public void create() { ExampleLibLoader.init(new Runnable() { @Override public void run() { - initLib(); + init = true; } }); @@ -40,12 +40,23 @@ public void run() { font = new BitmapFont(); } - private void initLib() { + + @Override + public void render() { + ScreenUtils.clear(0.4f, 0.4f, 0.4f, 1); + if(init) { + init = false; + initLib(); return; } - init = true; + batch.begin(); + font.draw(batch, "addIntValue " + a1 + " + " + b1 + " = " + ret1, 100, 100); + batch.end(); + } + + private void initLib() { NormalClass normalClass = new NormalClass(); IDLString string = new IDLString(); @@ -109,6 +120,7 @@ private void initLib() { System.out.println("operatorClass1 copy: " + operatorClass1.get_value()); testPrimitive(); + testArray(normalClass); // CustomLib.print(); } @@ -148,16 +160,39 @@ private void testPrimitive() { System.out.println("nullPointerReturnClass: " + nullPointerReturnClass); } - @Override - public void render() { - ScreenUtils.clear(0.4f, 0.4f, 0.4f, 1); - - if(!init) { - return; - } - - batch.begin(); - font.draw(batch, "addIntValue " + a1 + " + " + b1 + " = " + ret1, 100, 100); - batch.end(); + private void testArray(NormalClass normalClass) { + System.out.println("set intArray"); + normalClass.set_intArray(0, 1); + normalClass.set_intArray(1, 2); + normalClass.set_intArray(2, 3); + System.out.println("get intArray"); + int intArray0 = normalClass.get_intArray(0); + int intArray1 = normalClass.get_intArray(1); + int intArray2 = normalClass.get_intArray(2); + System.out.println("intArray0: " + intArray0); + System.out.println("intArray1: " + intArray1); + System.out.println("intArray2: " + intArray2); + + //Object value is updated from 10 to 11 even after getting the pointer + ReturnClass pointerClass1 = new ReturnClass(); + pointerClass1.set_value(10); + normalClass.set_pointerArray(0, pointerClass1); + ReturnClass pointerObject = normalClass.get_pointerArray(0); + float valuePointer = pointerObject.get_value(); + System.out.println("pointerClass1: " + valuePointer); + pointerClass1.set_value(11); + float valuePointerUpdated = pointerObject.get_value(); + System.out.println("pointerClass1 updated: " + valuePointerUpdated); + + //Object value is not updated from 10 to 11 because a object copy is made + ReturnClass valueClass1 = new ReturnClass(); + valueClass1.set_value(10); + normalClass.set_valueArray(0, valueClass1); + ReturnClass valueObject = normalClass.get_valueArray(0); + valueClass1.set_value(11); + float valueObj = valueObject.get_value(); + System.out.println("valueClass1: " + valueObj); + float valueObjUpdated = valueObject.get_value(); + System.out.println("valueClass1 updated: " + valueObjUpdated); } } \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/exampleLib.idl b/example/lib/lib-build/src/main/cpp/exampleLib.idl index 7c4c2192..ceb829fa 100644 --- a/example/lib/lib-build/src/main/cpp/exampleLib.idl +++ b/example/lib/lib-build/src/main/cpp/exampleLib.idl @@ -4,6 +4,9 @@ interface ParentClass { }; interface NormalClass { + [BoundsChecked] attribute long[] intArray; + [Value] attribute ReturnClass[] valueArray; + attribute ReturnClass[] pointerArray; attribute long hiddenInt; [Value] attribute ReturnClass valueReturnClass; attribute ReturnClass pointerReturnClass; diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/NormalClass.h b/example/lib/lib-build/src/main/cpp/source/exampleLib/src/NormalClass.h index 1184f80a..f1104732 100644 --- a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/NormalClass.h +++ b/example/lib/lib-build/src/main/cpp/source/exampleLib/src/NormalClass.h @@ -32,6 +32,10 @@ class NormalClass : public ParentClass ParamData data; public: + int intArray[3]; + ReturnClass valueArray[3]; + ReturnClass* pointerArray[3]; + enum EnumWithinClass { e_val = 34 }; diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index 0b8fc264..480cc371 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -52,46 +52,89 @@ public class CppCodeParser extends IDLDefaultCodeParser { protected static final String ATTRIBUTE_SET_PRIMITIVE_STATIC_TEMPLATE = "\n[TYPE]::[ATTRIBUTE] = [ATTRIBUTE];\n"; + protected static final String ATTRIBUTE_ARRAY_SET_PRIMITIVE_STATIC_TEMPLATE = + "\n[TYPE]::[ATTRIBUTE][index] = [ATTRIBUTE];\n"; + protected static final String ATTRIBUTE_SET_PRIMITIVE_TEMPLATE = "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + "nativeObject->[ATTRIBUTE] = [CAST][ATTRIBUTE];\n"; + protected static final String ATTRIBUTE_ARRAY_SET_PRIMITIVE_TEMPLATE = + "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + + "nativeObject->[ATTRIBUTE][index] = [CAST][ATTRIBUTE];\n"; + protected static final String ATTRIBUTE_SET_OBJECT_POINTER_STATIC_TEMPLATE = "\n[TYPE]::[ATTRIBUTE] = ([ATTRIBUTE_TYPE]*)[ATTRIBUTE]_addr;\n"; + protected static final String ATTRIBUTE_ARRAY_SET_OBJECT_POINTER_STATIC_TEMPLATE = + "\n[TYPE]::[ATTRIBUTE][index] = ([ATTRIBUTE_TYPE]*)[ATTRIBUTE]_addr;\n"; + protected static final String ATTRIBUTE_SET_OBJECT_POINTER_TEMPLATE = "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + "nativeObject->[ATTRIBUTE] = ([ATTRIBUTE_TYPE]*)[ATTRIBUTE]_addr;\n"; + protected static final String ATTRIBUTE_ARRAY_SET_OBJECT_POINTER_TEMPLATE = + "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + + "nativeObject->[ATTRIBUTE][index] = ([ATTRIBUTE_TYPE]*)[ATTRIBUTE]_addr;\n"; + protected static final String ATTRIBUTE_SET_OBJECT_VALUE_STATIC_TEMPLATE = "\n[TYPE]::[ATTRIBUTE] = *(([ATTRIBUTE_TYPE]*)[ATTRIBUTE]_addr);\n"; + protected static final String ATTRIBUTE_ARRAY_SET_OBJECT_VALUE_STATIC_TEMPLATE = + "\n[TYPE]::[ATTRIBUTE][index] = *(([ATTRIBUTE_TYPE]*)[ATTRIBUTE]_addr);\n"; + protected static final String ATTRIBUTE_SET_OBJECT_VALUE_TEMPLATE = "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + "nativeObject->[ATTRIBUTE] = *(([ATTRIBUTE_TYPE]*)[ATTRIBUTE]_addr);\n"; + protected static final String ATTRIBUTE_ARRAY_SET_OBJECT_VALUE_TEMPLATE = + "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + + "nativeObject->[ATTRIBUTE][index] = *(([ATTRIBUTE_TYPE]*)[ATTRIBUTE]_addr);\n"; + protected static final String ATTRIBUTE_GET_OBJECT_VALUE_STATIC_TEMPLATE = "\nreturn (jlong)&[TYPE]::[ATTRIBUTE];\n"; + protected static final String ATTRIBUTE_ARRAY_GET_OBJECT_VALUE_STATIC_TEMPLATE = + "\nreturn (jlong)&[TYPE]::[ATTRIBUTE][index];\n"; + protected static final String ATTRIBUTE_GET_OBJECT_VALUE_TEMPLATE = "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + "return (jlong)&nativeObject->[ATTRIBUTE];\n"; + protected static final String ATTRIBUTE_ARRAY_GET_OBJECT_VALUE_TEMPLATE = + "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + + "return (jlong)&nativeObject->[ATTRIBUTE][index];\n"; + protected static final String ATTRIBUTE_GET_OBJECT_POINTER_STATIC_TEMPLATE = "\nreturn (jlong)[TYPE]::[ATTRIBUTE];\n"; + protected static final String ATTRIBUTE_ARRAY_GET_OBJECT_POINTER_STATIC_TEMPLATE = + "\nreturn (jlong)([TYPE]::[ATTRIBUTE][index]);\n"; + protected static final String ATTRIBUTE_GET_OBJECT_POINTER_TEMPLATE = "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + "[CONST][ATTRIBUTE_TYPE]* attr = nativeObject->[ATTRIBUTE];\n" + "return (jlong)attr;\n"; + protected static final String ATTRIBUTE_ARRAY_GET_OBJECT_POINTER_TEMPLATE = + "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + + "[CONST][ATTRIBUTE_TYPE]* attr = (nativeObject->[ATTRIBUTE][index]);\n" + + "return (jlong)attr;\n"; + protected static final String ATTRIBUTE_GET_PRIMITIVE_STATIC_TEMPLATE = "\nreturn [TYPE]::[ATTRIBUTE];\n"; + protected static final String ATTRIBUTE_ARRAY_GET_PRIMITIVE_STATIC_TEMPLATE = + "\nreturn [TYPE]::[ATTRIBUTE][index];\n"; + protected static final String ATTRIBUTE_GET_PRIMITIVE_TEMPLATE = "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + "return [CAST]nativeObject->[ATTRIBUTE];\n"; + protected static final String ATTRIBUTE_ARRAY_GET_PRIMITIVE_TEMPLATE = + "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + + "return [CAST]nativeObject->[ATTRIBUTE][index];\n"; + protected static final String METHOD_GET_OBJ_VALUE_TEMPLATE = "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + "static [COPY_TYPE] [COPY_PARAM];\n" + @@ -230,49 +273,97 @@ public void onIDLAttributeGenerated(JParser jParser, IDLAttribute idlAttribute, .replace(TEMPLATE_TAG_ATTRIBUTE_TYPE, attributeType) .replace(TEMPLATE_TAG_TYPE, classTypeName); break; + case SET_ARRAY_OBJECT_VALUE: + content = ATTRIBUTE_ARRAY_SET_OBJECT_VALUE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName) + .replace(TEMPLATE_TAG_ATTRIBUTE_TYPE, attributeType) + .replace(TEMPLATE_TAG_TYPE, classTypeName); + break; case SET_OBJECT_VALUE_STATIC: content = ATTRIBUTE_SET_OBJECT_VALUE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName) .replace(TEMPLATE_TAG_ATTRIBUTE_TYPE, attributeType) .replace(TEMPLATE_TAG_TYPE, classTypeName); break; + case SET_ARRAY_OBJECT_VALUE_STATIC: + content = ATTRIBUTE_ARRAY_SET_OBJECT_VALUE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName) + .replace(TEMPLATE_TAG_ATTRIBUTE_TYPE, attributeType) + .replace(TEMPLATE_TAG_TYPE, classTypeName); + break; case GET_OBJECT_VALUE: content = ATTRIBUTE_GET_OBJECT_VALUE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName) .replace(TEMPLATE_TAG_ATTRIBUTE_TYPE, attributeType) .replace(TEMPLATE_TAG_TYPE, classTypeName); break; + case GET_ARRAY_OBJECT_VALUE: + content = ATTRIBUTE_ARRAY_GET_OBJECT_VALUE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName) + .replace(TEMPLATE_TAG_ATTRIBUTE_TYPE, attributeType) + .replace(TEMPLATE_TAG_TYPE, classTypeName); + break; case GET_OBJECT_VALUE_STATIC: content = ATTRIBUTE_GET_OBJECT_VALUE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName) .replace(TEMPLATE_TAG_ATTRIBUTE_TYPE, attributeType) .replace(TEMPLATE_TAG_TYPE, classTypeName); break; + case GET_ARRAY_OBJECT_VALUE_STATIC: + content = ATTRIBUTE_ARRAY_GET_OBJECT_VALUE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName) + .replace(TEMPLATE_TAG_ATTRIBUTE_TYPE, attributeType) + .replace(TEMPLATE_TAG_TYPE, classTypeName); + break; case SET_OBJECT_POINTER: content = ATTRIBUTE_SET_OBJECT_POINTER_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName) .replace(TEMPLATE_TAG_ATTRIBUTE_TYPE, attributeType) .replace(TEMPLATE_TAG_TYPE, classTypeName); break; + case SET_ARRAY_OBJECT_POINTER: + content = ATTRIBUTE_ARRAY_SET_OBJECT_POINTER_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName) + .replace(TEMPLATE_TAG_ATTRIBUTE_TYPE, attributeType) + .replace(TEMPLATE_TAG_TYPE, classTypeName); + break; case SET_OBJECT_POINTER_STATIC: content = ATTRIBUTE_SET_OBJECT_POINTER_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName) .replace(TEMPLATE_TAG_ATTRIBUTE_TYPE, attributeType) .replace(TEMPLATE_TAG_TYPE, classTypeName); break; + case SET_ARRAY_OBJECT_POINTER_STATIC: + content = ATTRIBUTE_ARRAY_SET_OBJECT_POINTER_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName) + .replace(TEMPLATE_TAG_ATTRIBUTE_TYPE, attributeType) + .replace(TEMPLATE_TAG_TYPE, classTypeName); + break; case GET_OBJECT_POINTER: content = ATTRIBUTE_GET_OBJECT_POINTER_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_ATTRIBUTE_TYPE, attributeType).replace(TEMPLATE_TAG_CONST, constTag); break; + case GET_ARRAY_OBJECT_POINTER: + content = ATTRIBUTE_ARRAY_GET_OBJECT_POINTER_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_ATTRIBUTE_TYPE, attributeType).replace(TEMPLATE_TAG_CONST, constTag); + break; case GET_OBJECT_POINTER_STATIC: content = ATTRIBUTE_GET_OBJECT_POINTER_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName); break; + case GET_ARRAY_OBJECT_POINTER_STATIC: + content = ATTRIBUTE_ARRAY_GET_OBJECT_POINTER_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName); + break; case SET_PRIMITIVE: content = ATTRIBUTE_SET_PRIMITIVE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_CAST, attributeReturnCast); break; case SET_PRIMITIVE_STATIC: content = ATTRIBUTE_SET_PRIMITIVE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName); break; + case SET_ARRAY_PRIMITIVE_STATIC: + content = ATTRIBUTE_ARRAY_SET_PRIMITIVE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName); + break; + case SET_ARRAY_PRIMITIVE: + content = ATTRIBUTE_ARRAY_SET_PRIMITIVE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_CAST, attributeReturnCast); + break; case GET_PRIMITIVE: content = ATTRIBUTE_GET_PRIMITIVE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_CAST, getPrimitiveCast); break; + case GET_ARRAY_PRIMITIVE: + content = ATTRIBUTE_ARRAY_GET_PRIMITIVE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_CAST, getPrimitiveCast); + break; case GET_PRIMITIVE_STATIC: content = ATTRIBUTE_GET_PRIMITIVE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName); break; + case GET_ARRAY_PRIMITIVE_STATIC: + content = ATTRIBUTE_ARRAY_GET_PRIMITIVE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, classTypeName); + break; } if(content != null) { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java index 2dbe1dc8..fd292c70 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java @@ -51,7 +51,6 @@ public void initAttribute(String line) { if(type.contains("[]")) { isArray = true; type = type.replace("[]", "").trim(); - type = type+"[]"; } if(type.endsWith("long") || type.endsWith("long[]")) { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeOperation.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeOperation.java index d5505a24..b13be31c 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeOperation.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeOperation.java @@ -10,8 +10,8 @@ public class IDLAttributeOperation { public static Op getEnum(boolean isSet, IDLAttribute idlAttribute, MethodDeclaration methodDeclaration, MethodDeclaration nativeMethod) { boolean isStatic = methodDeclaration.isStatic(); - Type nativeReturnType = nativeMethod.getType(); boolean isValue = idlAttribute.isValue; + boolean isArray = idlAttribute.isArray; Type returnType = methodDeclaration.getType(); NodeList parameters = methodDeclaration.getParameters(); @@ -46,31 +46,90 @@ public static Op getEnum(boolean isSet, IDLAttribute idlAttribute, MethodDeclara } } } + else if(isArray) { + if(parameters.get(1).getType().isClassOrInterfaceType()) { + if(isValue) { + if(isStatic) { + return Op.SET_ARRAY_OBJECT_VALUE_STATIC; + } + else { + return Op.SET_ARRAY_OBJECT_VALUE; + } + } + else { + // is pointer + if(isStatic) { + return Op.SET_ARRAY_OBJECT_POINTER_STATIC; + } + else { + return Op.SET_ARRAY_OBJECT_POINTER; + } + } + } + else { + if(isStatic) { + return Op.SET_ARRAY_PRIMITIVE_STATIC; + } + else { + return Op.SET_ARRAY_PRIMITIVE; + } + } + } } else if(returnType.isClassOrInterfaceType()) { - if(isValue) { - if(isStatic) { - return Op.GET_OBJECT_VALUE_STATIC; + if(isArray) { + if(isValue) { + if(isStatic) { + return Op.GET_ARRAY_OBJECT_VALUE_STATIC; + } + else { + return Op.GET_ARRAY_OBJECT_VALUE; + } } else { - return Op.GET_OBJECT_VALUE; + if(isStatic) { + return Op.GET_ARRAY_OBJECT_POINTER_STATIC; + } + else { + return Op.GET_ARRAY_OBJECT_POINTER; + } } } else { - if(isStatic) { - return Op.GET_OBJECT_POINTER_STATIC; + if(isValue) { + if(isStatic) { + return Op.GET_OBJECT_VALUE_STATIC; + } + else { + return Op.GET_OBJECT_VALUE; + } } else { - return Op.GET_OBJECT_POINTER; + if(isStatic) { + return Op.GET_OBJECT_POINTER_STATIC; + } + else { + return Op.GET_OBJECT_POINTER; + } } } } else { - if(isStatic) { - return Op.GET_PRIMITIVE_STATIC; + if(isArray) { + if(isStatic) { + return Op.GET_ARRAY_PRIMITIVE_STATIC; + } + else { + return Op.GET_ARRAY_PRIMITIVE; + } } else { - return Op.GET_PRIMITIVE; + if(isStatic) { + return Op.GET_PRIMITIVE_STATIC; + } + else { + return Op.GET_PRIMITIVE; + } } } return null; @@ -91,5 +150,22 @@ public enum Op { SET_PRIMITIVE_STATIC, GET_PRIMITIVE, GET_PRIMITIVE_STATIC, + + // Array + + SET_ARRAY_OBJECT_VALUE, + SET_ARRAY_OBJECT_VALUE_STATIC, + GET_ARRAY_OBJECT_VALUE, + GET_ARRAY_OBJECT_VALUE_STATIC, + + SET_ARRAY_OBJECT_POINTER, + SET_ARRAY_OBJECT_POINTER_STATIC, + GET_ARRAY_OBJECT_POINTER, + GET_ARRAY_OBJECT_POINTER_STATIC, + + SET_ARRAY_PRIMITIVE, + SET_ARRAY_PRIMITIVE_STATIC, + GET_ARRAY_PRIMITIVE, + GET_ARRAY_PRIMITIVE_STATIC, } } \ No newline at end of file diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java index 6bc038a2..6daa5cd0 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java @@ -97,6 +97,11 @@ public static void generateAttribute(IDLDefaultCodeParser idlParser, JParser jPa String getMethodName = ATTRIBUTE_PREFIX_GET + attributeName; getMethodDeclaration = classOrInterfaceDeclaration.addMethod(getMethodName, Modifier.Keyword.PUBLIC); getMethodDeclaration.setStatic(idlAttribute.isStatic); + + if(idlAttribute.isArray) { + getMethodDeclaration.addAndGetParameter("int", "index"); + } + getMethodDeclaration.setType(type); JParserHelper.addMissingImportType(jParser, unit, type); IDLDefaultCodeParser.setDefaultReturnValues(jParser, unit, type, getMethodDeclaration); @@ -117,6 +122,9 @@ public static void generateAttribute(IDLDefaultCodeParser idlParser, JParser jPa String setMethodName = ATTRIBUTE_PREFIX_SET + attributeName; setMethodDeclaration = classOrInterfaceDeclaration.addMethod(setMethodName, Modifier.Keyword.PUBLIC); setMethodDeclaration.setStatic(idlAttribute.isStatic); + if(idlAttribute.isArray) { + setMethodDeclaration.addAndGetParameter("int", "index"); + } Parameter parameter = setMethodDeclaration.addAndGetParameter(type, attributeName); Type paramType = parameter.getType(); JParserHelper.addMissingImportType(jParser, unit, paramType); diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index d5a12d2d..cdb486a9 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -108,45 +108,88 @@ public class TeaVMCodeParser extends IDLDefaultCodeParser { "var jsObj = [MODULE].wrapPointer(this_addr, [MODULE].[TYPE]);\n" + "return jsObj.get_[ATTRIBUTE]();"; + protected static final String ATTRIBUTE_ARRAY_GET_PRIMITIVE_TEMPLATE = + "var jsObj = [MODULE].wrapPointer(this_addr, [MODULE].[TYPE]);\n" + + "return jsObj.get_[ATTRIBUTE](index);"; + protected static final String ATTRIBUTE_GET_PRIMITIVE_STATIC_TEMPLATE = "return [MODULE].[TYPE].prototype.get_[ATTRIBUTE]()"; + protected static final String ATTRIBUTE_ARRAY_GET_PRIMITIVE_STATIC_TEMPLATE = + "return [MODULE].[TYPE].prototype.get_[ATTRIBUTE](index)"; + protected static final String ATTRIBUTE_GET_OBJECT_POINTER_STATIC_TEMPLATE = "var returnedJSObj = [MODULE].[TYPE].prototype.get_[ATTRIBUTE]();\n" + "if(!returnedJSObj.hasOwnProperty('ptr')) return 0; \n" + "return [MODULE].getPointer(returnedJSObj);"; + protected static final String ATTRIBUTE_ARRAY_GET_OBJECT_POINTER_STATIC_TEMPLATE = + "var returnedJSObj = [MODULE].[TYPE].prototype.get_[ATTRIBUTE](index);\n" + + "if(!returnedJSObj.hasOwnProperty('ptr')) return 0; \n" + + "return [MODULE].getPointer(returnedJSObj);"; + protected static final String ATTRIBUTE_GET_OBJECT_POINTER_TEMPLATE = "var jsObj = [MODULE].wrapPointer(this_addr, [MODULE].[TYPE]);\n" + "var returnedJSObj = jsObj.get_[ATTRIBUTE]();\n" + "if(!returnedJSObj.hasOwnProperty('ptr')) return 0; \n" + "return [MODULE].getPointer(returnedJSObj);"; + protected static final String ATTRIBUTE_ARRAY_GET_OBJECT_POINTER_TEMPLATE = + "var jsObj = [MODULE].wrapPointer(this_addr, [MODULE].[TYPE]);\n" + + "var returnedJSObj = jsObj.get_[ATTRIBUTE](index);\n" + + "if(!returnedJSObj.hasOwnProperty('ptr')) return 0; \n" + + "return [MODULE].getPointer(returnedJSObj);"; + protected static final String ATTRIBUTE_SET_OBJECT_POINTER_TEMPLATE = "var jsObj = [MODULE].wrapPointer(this_addr, [MODULE].[TYPE]);\n" + "jsObj.set_[ATTRIBUTE]([ATTRIBUTE]_addr);"; + protected static final String ATTRIBUTE_ARRAY_SET_OBJECT_POINTER_TEMPLATE = + "var jsObj = [MODULE].wrapPointer(this_addr, [MODULE].[TYPE]);\n" + + "jsObj.set_[ATTRIBUTE](index, [ATTRIBUTE]_addr);"; + protected static final String ATTRIBUTE_SET_OBJECT_POINTER_STATIC_TEMPLATE = "[MODULE].[TYPE].prototype.set_[ATTRIBUTE]([ATTRIBUTE]_addr);\n"; + protected static final String ATTRIBUTE_ARRAY_SET_OBJECT_POINTER_STATIC_TEMPLATE = + "[MODULE].[TYPE].prototype.set_[ATTRIBUTE](index, [ATTRIBUTE]_addr);\n"; + protected static final String ATTRIBUTE_SET_OBJECT_VALUE_TEMPLATE = "var jsObj = [MODULE].wrapPointer(this_addr, [MODULE].[TYPE]);\n" + "jsObj.set_[ATTRIBUTE]([ATTRIBUTE]_addr);"; + protected static final String ATTRIBUTE_ARRAY_SET_OBJECT_VALUE_TEMPLATE = + "var jsObj = [MODULE].wrapPointer(this_addr, [MODULE].[TYPE]);\n" + + "jsObj.set_[ATTRIBUTE](index, [ATTRIBUTE]_addr);"; + protected static final String ATTRIBUTE_SET_OBJECT_VALUE_STATIC_TEMPLATE = "[MODULE].[TYPE].prototype.set_[ATTRIBUTE]([ATTRIBUTE]_addr);\n"; + protected static final String ATTRIBUTE_ARRAY_SET_OBJECT_VALUE_STATIC_TEMPLATE = + "[MODULE].[TYPE].prototype.set_[ATTRIBUTE](index, [ATTRIBUTE]_addr);\n"; + protected static final String ATTRIBUTE_SET_PRIMITIVE_TEMPLATE = "var jsObj = [MODULE].wrapPointer(this_addr, [MODULE].[TYPE]);\n" + "jsObj.set_[ATTRIBUTE]([ATTRIBUTE]);"; + protected static final String ATTRIBUTE_ARRAY_SET_PRIMITIVE_TEMPLATE = + "var jsObj = [MODULE].wrapPointer(this_addr, [MODULE].[TYPE]);\n" + + "jsObj.set_[ATTRIBUTE](index, [ATTRIBUTE]);"; + protected static final String ATTRIBUTE_SET_PRIMITIVE_STATIC_TEMPLATE = "[MODULE].[TYPE].prototype.set_[ATTRIBUTE]([ATTRIBUTE]);\n"; + protected static final String ATTRIBUTE_ARRAY_SET_PRIMITIVE_STATIC_TEMPLATE = + "[MODULE].[TYPE].prototype.set_[ATTRIBUTE](index, [ATTRIBUTE]);\n"; + protected static final String ATTRIBUTE_GET_OBJECT_VALUE_STATIC_TEMPLATE = ATTRIBUTE_GET_OBJECT_POINTER_STATIC_TEMPLATE; + protected static final String ATTRIBUTE_ARRAY_GET_OBJECT_VALUE_STATIC_TEMPLATE = ATTRIBUTE_ARRAY_GET_OBJECT_POINTER_STATIC_TEMPLATE; + protected static final String ATTRIBUTE_GET_OBJECT_VALUE_TEMPLATE = ATTRIBUTE_GET_OBJECT_POINTER_TEMPLATE; + protected static final String ATTRIBUTE_ARRAY_GET_OBJECT_VALUE_TEMPLATE = ATTRIBUTE_ARRAY_GET_OBJECT_POINTER_TEMPLATE; + protected static final String ENUM_GET_INT_TEMPLATE = "\nreturn [MODULE].[ENUM];\n"; @@ -398,43 +441,83 @@ public void onIDLAttributeGenerated(JParser jParser, IDLAttribute idlAttribute, case SET_OBJECT_VALUE: content = ATTRIBUTE_SET_OBJECT_VALUE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); break; + case SET_ARRAY_OBJECT_VALUE: + content = ATTRIBUTE_ARRAY_SET_OBJECT_VALUE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); + break; case SET_OBJECT_VALUE_STATIC: content = ATTRIBUTE_SET_OBJECT_VALUE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); break; + case SET_ARRAY_OBJECT_VALUE_STATIC: + content = ATTRIBUTE_ARRAY_SET_OBJECT_VALUE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); + break; case GET_OBJECT_VALUE: content = ATTRIBUTE_GET_OBJECT_VALUE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName) .replace(TEMPLATE_TAG_TYPE, returnTypeName) .replace(TEMPLATE_TAG_MODULE, module); break; + case GET_ARRAY_OBJECT_VALUE: + content = ATTRIBUTE_ARRAY_GET_OBJECT_VALUE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName) + .replace(TEMPLATE_TAG_TYPE, returnTypeName) + .replace(TEMPLATE_TAG_MODULE, module); + break; case GET_OBJECT_VALUE_STATIC: content = ATTRIBUTE_GET_OBJECT_VALUE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName) .replace(TEMPLATE_TAG_TYPE, returnTypeName) .replace(TEMPLATE_TAG_MODULE, module); break; + case GET_ARRAY_OBJECT_VALUE_STATIC: + content = ATTRIBUTE_ARRAY_GET_OBJECT_VALUE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName) + .replace(TEMPLATE_TAG_TYPE, returnTypeName) + .replace(TEMPLATE_TAG_MODULE, module); + break; case SET_OBJECT_POINTER: content = ATTRIBUTE_SET_OBJECT_POINTER_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); break; + case SET_ARRAY_OBJECT_POINTER: + content = ATTRIBUTE_ARRAY_SET_OBJECT_POINTER_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); + break; case SET_OBJECT_POINTER_STATIC: content = ATTRIBUTE_SET_OBJECT_POINTER_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); break; + case SET_ARRAY_OBJECT_POINTER_STATIC: + content = ATTRIBUTE_ARRAY_SET_OBJECT_POINTER_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); + break; case GET_OBJECT_POINTER: content = ATTRIBUTE_GET_OBJECT_POINTER_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); break; + case GET_ARRAY_OBJECT_POINTER: + content = ATTRIBUTE_ARRAY_GET_OBJECT_POINTER_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); + break; case GET_OBJECT_POINTER_STATIC: content = ATTRIBUTE_GET_OBJECT_POINTER_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); break; + case GET_ARRAY_OBJECT_POINTER_STATIC: + content = ATTRIBUTE_ARRAY_GET_OBJECT_POINTER_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); + break; case SET_PRIMITIVE: content = ATTRIBUTE_SET_PRIMITIVE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); break; + case SET_ARRAY_PRIMITIVE: + content = ATTRIBUTE_ARRAY_SET_PRIMITIVE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); + break; case SET_PRIMITIVE_STATIC: content = ATTRIBUTE_SET_PRIMITIVE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); break; + case SET_ARRAY_PRIMITIVE_STATIC: + content = ATTRIBUTE_ARRAY_SET_PRIMITIVE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); + break; case GET_PRIMITIVE: content = ATTRIBUTE_GET_PRIMITIVE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); break; + case GET_ARRAY_PRIMITIVE: + content = ATTRIBUTE_ARRAY_GET_PRIMITIVE_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); + break; case GET_PRIMITIVE_STATIC: content = ATTRIBUTE_GET_PRIMITIVE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); break; + case GET_ARRAY_PRIMITIVE_STATIC: + content = ATTRIBUTE_ARRAY_GET_PRIMITIVE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_ATTRIBUTE, attributeName).replace(TEMPLATE_TAG_TYPE, returnTypeName).replace(TEMPLATE_TAG_MODULE, module); + break; } if(content != null) { From bad42a3779285540034ad516cb7eb751693d226f Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 13 Aug 2024 21:08:41 -0300 Subject: [PATCH 048/186] Code gen improvements --- .../src/main/cpp/custom/CustomCode.h | 1 + .../lib/lib-build/src/main/cpp/exampleLib.idl | 38 ++++++++++ .../main/cpp/source/exampleLib/src/TestLib.h | 76 +++++++++++++++++++ .../github/xpenatan/jparser/core/JParser.java | 12 +++ .../xpenatan/jparser/cpp/CppCodeParser.java | 15 ++++ .../jparser/cpp/NativeCPPGenerator.java | 1 - .../xpenatan/jparser/idl/IDLHelper.java | 2 + .../idl/parser/IDLClassGeneratorParser.java | 4 +- .../jparser/teavm/TeaVMCodeParser.java | 44 ++++++++++- 9 files changed, 188 insertions(+), 5 deletions(-) create mode 100644 example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h diff --git a/example/lib/lib-build/src/main/cpp/custom/CustomCode.h b/example/lib/lib-build/src/main/cpp/custom/CustomCode.h index 349b4026..5f54ffd2 100644 --- a/example/lib/lib-build/src/main/cpp/custom/CustomCode.h +++ b/example/lib/lib-build/src/main/cpp/custom/CustomCode.h @@ -6,6 +6,7 @@ #include "DefaultInterface.h" #include "subpackage/ParamData.h" #include "DefaultParamsClass.h" +#include "TestLib.h" typedef NormalClass::EnumWithinClass EnumWithinClass; typedef NormalClass::EnumClassWithinClass EnumClassWithinClass; diff --git a/example/lib/lib-build/src/main/cpp/exampleLib.idl b/example/lib/lib-build/src/main/cpp/exampleLib.idl index ceb829fa..4e51324f 100644 --- a/example/lib/lib-build/src/main/cpp/exampleLib.idl +++ b/example/lib/lib-build/src/main/cpp/exampleLib.idl @@ -1,3 +1,41 @@ +interface TestObjectClass { + void TestObjectClass(); + attribute long intValue; + attribute float floatValue; +}; + +interface TestAttributeArrayClass { + void TestAttributeArrayClass(); + [BoundsChecked] attribute long[] intArray; + attribute float[] floatArray; + attribute byte[] byteArray; + attribute boolean[] boolArray; + [Value] attribute TestObjectClass[] valueObjectArray; + attribute TestObjectClass[] pointerObjectArray; +}; + +interface TestAttributeClass { + void TestAttributeClass(); + readonly attribute long readOnlyIntValue; + attribute long intValue; + attribute float floatValue; + attribute double doubleValue; + attribute boolean boolValue; + attribute any voidPointer; + [Value] attribute TestObjectClass valueObject; + attribute TestObjectClass pointerObject; + attribute TestObjectClass nullPointerObject; +}; + +interface TestConstructorClass { + void TestConstructorClass(long intParam); + void TestConstructorClass(float floatParam, boolean boolParam); + void TestConstructorClass(long intParam, long intParam2, float floatParam, float floatParam2, optional boolean boolParam); + void TestConstructorClass(long intParam, long[] intArray, float[] floatArray); +}; + + + interface ParentClass { float addFloatValue(float a, float b); boolean invertBoolean(boolean value); diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h new file mode 100644 index 00000000..0d011966 --- /dev/null +++ b/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h @@ -0,0 +1,76 @@ +#pragma once + +#include +#include +#include +#include + +using namespace std; + +class TestObjectClass { + private: + + public: + int intValue; + float floatValue; +}; + +class TestAttributeArrayClass { + private: + + public: + int intArray[3]; + float floatArray[3]; + char byteArray[3]; + bool boolArray[3]; + TestObjectClass valueObjectArray[3]; + TestObjectClass* pointerObjectArray[3]; +}; + +class TestAttributeClass { + private: + + public: + const int readOnlyIntValue; + int intValue; + float floatValue; + double doubleValue; + bool boolValue; + void* voidPointer; + TestObjectClass valueObject; + TestObjectClass* pointerObject; + TestObjectClass* nullPointerObject; + + TestAttributeClass(): readOnlyIntValue(7) { + pointerObject = new TestObjectClass(); + nullPointerObject = NULL; + }; + ~TestAttributeClass() { + delete pointerObject; + }; +}; + +class TestConstructorClass { + private: + + public: + int intParam; + float floatParam; + bool boolParam; + + TestConstructorClass(int intParam) { + this->intParam = intParam; + }; + TestConstructorClass(float floatParam, bool boolParam) { + this->floatParam = floatParam; + this->boolParam = boolParam; + }; + TestConstructorClass(int intParam, int intParam2, float floatParam, float floatParam2, bool boolParam = true) { + this->intParam = intParam; + this->floatParam = floatParam; + this->boolParam = boolParam; + }; + TestConstructorClass(int intParam, int* intArray, float* floatArray) { + this->intParam = intParam; + }; +}; \ No newline at end of file diff --git a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParser.java b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParser.java index 9ea6c9dc..bfe071b4 100644 --- a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParser.java +++ b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParser.java @@ -1,11 +1,16 @@ package com.github.xpenatan.jparser.core; +import com.github.javaparser.ParserConfiguration; import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.PackageDeclaration; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.comments.BlockComment; +import com.github.javaparser.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.JavaSymbolSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; import com.github.javaparser.utils.PositionUtils; import com.github.xpenatan.jparser.core.codeparser.CodeParser; import com.github.xpenatan.jparser.core.codeparser.CodeParserItem; @@ -87,6 +92,13 @@ public static void generate(CodeParser wrapper, String sourceDir, String genDir, } System.out.println("***** GENERATING CODE *****"); JParser jParser = new JParser(sourceD, genD); + + CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver(); + combinedTypeSolver.add(new ReflectionTypeSolver()); + // Configure JavaParser to use type resolution + JavaSymbolSolver symbolSolver = new JavaSymbolSolver(combinedTypeSolver); + StaticJavaParser.getParserConfiguration().setSymbolResolver(symbolSolver); + processDirectory(jParser, fileSourceDir, fileGenDir, excludes, fileSourceDir); wrapper.onParseStart(jParser); parseJavaFiles(jParser, wrapper); diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index 480cc371..01ce33ff 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -541,6 +541,21 @@ private static String getParam(IDLFile idlFile, Type type, String paramName, Str else if(isAny) { paramName = "( void* )" + paramName; } + else { + // basic param cast jni java primitive to c++ primitive. + if(classType.equals("int")) { + paramName = "(int)" + paramName; + } + else if(classType.equals("float")) { + paramName = "(float)" + paramName; + } + else if(classType.equals("double")) { + paramName = "(double)" + paramName; + } + else if(classType.equals("boolean")) { + paramName = "(bool)" + paramName; + } + } IDLEnum anEnum = idlFile.getEnum(classType); if(anEnum != null) { diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/NativeCPPGenerator.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/NativeCPPGenerator.java index 864a7162..b1c80db5 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/NativeCPPGenerator.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/NativeCPPGenerator.java @@ -10,7 +10,6 @@ import com.github.xpenatan.jparser.core.util.CustomFileDescriptor; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLHelper.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLHelper.java index 805078e7..c09eceec 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLHelper.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLHelper.java @@ -1,7 +1,9 @@ package com.github.xpenatan.jparser.idl; +import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.type.ClassOrInterfaceType; import com.github.javaparser.ast.type.Type; +import java.io.ByteArrayInputStream; public class IDLHelper { public static String removeMultipleSpaces(String in) { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java index 560cf4bc..58166756 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java @@ -184,8 +184,8 @@ private CompilationUnit setupClass(IDLClassOrEnum idlClass, String subPackage) { IDLMethodParser.generateFieldName("T_02", classDeclaration, className, true, Modifier.Keyword.PUBLIC, true); IDLMethodParser.generateFieldName("T_03", classDeclaration, className, true, Modifier.Keyword.PUBLIC, true); } - - return compilationUnit; + // Hack to inject internal dependencies + return StaticJavaParser.parse(compilationUnit.toString()); } @Override diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index cdb486a9..64681938 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -23,6 +23,10 @@ import com.github.javaparser.ast.type.ArrayType; import com.github.javaparser.ast.type.ClassOrInterfaceType; import com.github.javaparser.ast.type.Type; +import com.github.javaparser.resolution.UnsolvedSymbolException; +import com.github.javaparser.resolution.types.ResolvedArrayType; +import com.github.javaparser.resolution.types.ResolvedReferenceType; +import com.github.javaparser.resolution.types.ResolvedType; import com.github.xpenatan.jparser.core.JParser; import com.github.xpenatan.jparser.core.JParserHelper; import com.github.xpenatan.jparser.core.JParserItem; @@ -679,6 +683,7 @@ private void convertNativeMethodLongType(ClassOrInterfaceDeclaration classDeclar for(int i = 0; i < constructorDeclarations.size(); i++) { ConstructorDeclaration constructorDeclaration = constructorDeclarations.get(i); List methodCallerExprList = constructorDeclaration.findAll(MethodCallExpr.class); + NodeList constructorParameters = constructorDeclaration.getParameters(); updateLongToInt(classDeclaration, methodCallerExprList); } @@ -739,10 +744,45 @@ private void updateLongToInt(ClassOrInterfaceDeclaration classDeclaration, List< } } - public MethodDeclaration getNativeMethod(ClassOrInterfaceDeclaration classDeclaration, MethodCallExpr methodCallExpr) { + private MethodDeclaration getNativeMethod(ClassOrInterfaceDeclaration classDeclaration, MethodCallExpr methodCallExpr) { String nativeMethodName = methodCallExpr.getNameAsString(); NodeList arguments = methodCallExpr.getArguments(); - List methodsByName = getNativeMethodsByName(classDeclaration, nativeMethodName, arguments.size(), null); + ArrayList paramTypes = new ArrayList<>(); + if(arguments.size() > 0) { + for(int i = 0; i < arguments.size(); i++) { + Expression expression = arguments.get(i); + ResolvedType resolvedType = null; + try { + resolvedType = expression.calculateResolvedType(); + } + catch(Throwable t) { + + if(t instanceof UnsolvedSymbolException) { + UnsolvedSymbolException unE = (UnsolvedSymbolException)t; + String name = unE.getName(); + paramTypes.add(name); + } + continue; + } + String type = null; + if(resolvedType.isPrimitive()) { + type = resolvedType.asPrimitive().describe(); + } + else if(resolvedType.isReferenceType()) { + ResolvedReferenceType referenceType1 = resolvedType.asReferenceType(); + String[] split = referenceType1.describe().split("\\."); + type = split[split.length-1]; + } + else if(resolvedType.isArray()) { + ResolvedArrayType arrayType = resolvedType.asArrayType(); + type = arrayType.describe(); + } + paramTypes.add(type); + } + } + String[] paramT = new String[paramTypes.size()]; + paramTypes.toArray(paramT); + List methodsByName = getNativeMethodsByName(classDeclaration, nativeMethodName, arguments.size(), paramT); int size = methodsByName.size(); if(size == 0) { return null; From 012c8ac6a8f3e6d857b54a4b22ec56575d809ea2 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 13 Aug 2024 22:06:27 -0300 Subject: [PATCH 049/186] Add enum, methods and string --- .../src/main/cpp/custom/CustomCode.h | 7 +- .../lib/lib-build/src/main/cpp/exampleLib.idl | 45 +++++++- .../cpp/source/exampleLib/src/NormalClass.h | 2 +- .../main/cpp/source/exampleLib/src/TestLib.h | 102 +++++++++++++++++- 4 files changed, 151 insertions(+), 5 deletions(-) diff --git a/example/lib/lib-build/src/main/cpp/custom/CustomCode.h b/example/lib/lib-build/src/main/cpp/custom/CustomCode.h index 5f54ffd2..17f0a084 100644 --- a/example/lib/lib-build/src/main/cpp/custom/CustomCode.h +++ b/example/lib/lib-build/src/main/cpp/custom/CustomCode.h @@ -10,4 +10,9 @@ typedef NormalClass::EnumWithinClass EnumWithinClass; typedef NormalClass::EnumClassWithinClass EnumClassWithinClass; -typedef EnumNamespace::EnumInNamespace EnumInNamespace; \ No newline at end of file +typedef EnumNamespace::EnumInNamespace EnumInNamespace; + + +typedef TestEnumClass::TestEnumWithinClass TestEnumWithinClass; +typedef TestEnumClass::TestEnumClassWithinClass TestEnumClassWithinClass; +typedef TestEnumNamespace::TestEnumInNamespace TestEnumInNamespace; \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/exampleLib.idl b/example/lib/lib-build/src/main/cpp/exampleLib.idl index 4e51324f..1b0ad4cf 100644 --- a/example/lib/lib-build/src/main/cpp/exampleLib.idl +++ b/example/lib/lib-build/src/main/cpp/exampleLib.idl @@ -25,16 +25,59 @@ interface TestAttributeClass { [Value] attribute TestObjectClass valueObject; attribute TestObjectClass pointerObject; attribute TestObjectClass nullPointerObject; + [Value] attribute IDLString strParam; }; interface TestConstructorClass { + [Value] attribute IDLString strParam; + void TestConstructorClass(long intParam); - void TestConstructorClass(float floatParam, boolean boolParam); + void TestConstructorClass(float floatParam, [Const] DOMString strParam); void TestConstructorClass(long intParam, long intParam2, float floatParam, float floatParam2, optional boolean boolParam); void TestConstructorClass(long intParam, long[] intArray, float[] floatArray); }; +interface TestMethodClass { + void TestMethodClass(); + void setMethod01(long intParam); + void setMethod02(float floatParam, boolean boolParam); + void setMethod03(long intParam, long intParam2, float floatParam, float floatParam2, optional boolean boolParam); + void setMethod04(long intParam, long[] intArray, float[] floatArray); + void setMethod05([Const] DOMString strParam); + void setMethod06([Const] TestObjectClass pointerObject01, TestObjectClass pointerObject02, [Const, Ref] TestObjectClass refObject01, [Ref] TestObjectClass refObject02); + + long getIntParam(); + long getIntParam2(); + float getFloatParam(); + float getFloatParam2(); + float getBoolParam(); + [Const, Value] IDLStringView getStrParam(); + [Const] TestObjectClass getPointerObject01(); + TestObjectClass getPointerObject02(); + [Const, Ref] TestObjectClass getRefObject01(); + [Ref] TestObjectClass getRefObject02(); + [Value] TestObjectClass getValueObject(); +}; + +enum TestEnumWithinClass { + "TestEnumClass::e_val" +}; + +enum TestEnumClassWithinClass { + "TestEnumClassWithinClass::testEnum" +}; + +enum TestEnumInNamespace { + "TestEnumInNamespace::e_namespace_val" +}; + +enum TestEnumLib { + "TEST_DEFAULT", + "TEST_FIRST", + "TEST_SECOND" +}; +// ########################################## interface ParentClass { float addFloatValue(float a, float b); diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/NormalClass.h b/example/lib/lib-build/src/main/cpp/source/exampleLib/src/NormalClass.h index f1104732..999076e8 100644 --- a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/NormalClass.h +++ b/example/lib/lib-build/src/main/cpp/source/exampleLib/src/NormalClass.h @@ -9,7 +9,7 @@ #include enum EnumLib : int { - DEFAULT = 10, + DEFAULT = 7, FIRST, SECOND, }; diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h index 0d011966..8e3bed70 100644 --- a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h @@ -40,6 +40,7 @@ class TestAttributeClass { TestObjectClass valueObject; TestObjectClass* pointerObject; TestObjectClass* nullPointerObject; + string strParam; TestAttributeClass(): readOnlyIntValue(7) { pointerObject = new TestObjectClass(); @@ -55,22 +56,119 @@ class TestConstructorClass { public: int intParam; + float intParam2; float floatParam; + float floatParam2; bool boolParam; + string strParam; TestConstructorClass(int intParam) { this->intParam = intParam; }; - TestConstructorClass(float floatParam, bool boolParam) { + TestConstructorClass(float floatParam, const char* strParam) { this->floatParam = floatParam; this->boolParam = boolParam; + this->strParam = strParam; }; TestConstructorClass(int intParam, int intParam2, float floatParam, float floatParam2, bool boolParam = true) { this->intParam = intParam; + this->intParam2 = intParam2; this->floatParam = floatParam; + this->floatParam2 = floatParam2; this->boolParam = boolParam; }; - TestConstructorClass(int intParam, int* intArray, float* floatArray) { + TestConstructorClass(int intParam, int* intArraySize2, float* floatArraySize2) { this->intParam = intParam; + intArraySize2[0] = 1; + intArraySize2[1] = 2; + floatArraySize2[0] = 3.1; + floatArraySize2[1] = 4.2; }; +}; + +class TestMethodClass { + private: + int intParam; + int intParam2; + float floatParam; + float floatParam2; + bool boolParam; + string strParam; + const TestObjectClass* pointerObject01; + TestObjectClass* pointerObject02; + TestObjectClass refObject01; + TestObjectClass refObject02; + public: + TestMethodClass() { + pointerObject01 = NULL; + pointerObject02 = NULL; + }; + void setMethod01(int intParam) { + this->intParam = intParam; + }; + void setMethod02(float floatParam, bool boolParam) { + this->floatParam = floatParam; + this->boolParam = boolParam; + }; + void setMethod03(int intParam, int intParam2, float floatParam, float floatParam2, bool boolParam = true) { + this->intParam = intParam; + this->intParam2 = intParam2; + this->floatParam = floatParam; + this->floatParam2 = floatParam2; + this->boolParam = boolParam; + }; + void setMethod04(int intParam, int* intArraySize2, float* floatArraySize2) { + this->intParam = intParam; + intArraySize2[0] = 1; + intArraySize2[1] = 2; + floatArraySize2[0] = 3.1; + floatArraySize2[1] = 4.2; + }; + void setMethod05(const char* strParam) { + this->strParam = strParam; + }; + void setMethod06(const TestObjectClass* pointerObject01, TestObjectClass* pointerObject02, const TestObjectClass& refObject01, TestObjectClass& refObject02) { + this->pointerObject01 = pointerObject01; + this->pointerObject02 = pointerObject02; + this->refObject01 = refObject01; + this->refObject02 = refObject02; + }; + + int getIntParam() { return intParam; }; + int getIntParam2() { return intParam2; }; + float getFloatParam() { return floatParam; }; + float getFloatParam2() { return floatParam2; }; + bool getBoolParam() { return boolParam; }; + const char* getStrParam() { return strParam.c_str(); }; + const TestObjectClass* getPointerObject01() { return pointerObject01; }; + TestObjectClass* getPointerObject02() { return pointerObject02; }; + const TestObjectClass& getRefObject01() { return refObject01; }; + TestObjectClass& getRefObject02() { return refObject02; }; + TestObjectClass getValueObject() { return refObject02; }; +}; + +class TestEnumClass { + private: + ParamData data; + + public: + enum TestEnumWithinClass { + e_val = 34 + }; + + enum class TestEnumClassWithinClass { + testEnum = 35 + }; +}; + +namespace TestEnumNamespace { + enum TestEnumInNamespace { + e_namespace_val = 78 + }; +}; + +enum TestEnumLib : int { + TEST_DEFAULT = 7, + TEST_FIRST, + TEST_SECOND }; \ No newline at end of file From 56a2f2f2f6158ee4cb8c8add4051b303fa952bcd Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 14 Aug 2024 08:59:13 -0300 Subject: [PATCH 050/186] Add static attribute/method --- .../lib/lib-build/src/main/cpp/exampleLib.idl | 31 +++++++++ .../main/cpp/source/exampleLib/src/TestLib.h | 68 +++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/example/lib/lib-build/src/main/cpp/exampleLib.idl b/example/lib/lib-build/src/main/cpp/exampleLib.idl index 1b0ad4cf..41d1114d 100644 --- a/example/lib/lib-build/src/main/cpp/exampleLib.idl +++ b/example/lib/lib-build/src/main/cpp/exampleLib.idl @@ -28,6 +28,15 @@ interface TestAttributeClass { [Value] attribute IDLString strParam; }; +[NoDelete] +interface TestStaticAttributeClass { + static attribute long staticIntValue; + static readonly attribute long staticConstIntValue; + static attribute float staticFloatValue; + static attribute double staticDoubleValue; + static attribute boolean staticBoolValue; +}; + interface TestConstructorClass { [Value] attribute IDLString strParam; @@ -59,6 +68,28 @@ interface TestMethodClass { [Value] TestObjectClass getValueObject(); }; +[NoDelete] +interface TestStaticMethodClass { + static void setMethod01(long intParam); + static void setMethod02(float floatParam, boolean boolParam); + static void setMethod03(long intParam, long intParam2, float floatParam, float floatParam2, optional boolean boolParam); + static void setMethod04(long intParam, long[] intArray, float[] floatArray); + static void setMethod05([Const] DOMString strParam); + static void setMethod06([Const] TestObjectClass pointerObject01, TestObjectClass pointerObject02, [Const, Ref] TestObjectClass refObject01, [Ref] TestObjectClass refObject02); + + static long getIntParam(); + static long getIntParam2(); + static float getFloatParam(); + static float getFloatParam2(); + static float getBoolParam(); + [Const, Value] static IDLStringView getStrParam(); + [Const] static TestObjectClass getPointerObject01(); + static TestObjectClass getPointerObject02(); + [Const, Ref] static TestObjectClass getRefObject01(); + [Ref] static TestObjectClass getRefObject02(); + [Value] static TestObjectClass getValueObject(); +}; + enum TestEnumWithinClass { "TestEnumClass::e_val" }; diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h index 8e3bed70..d9134193 100644 --- a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h @@ -51,6 +51,17 @@ class TestAttributeClass { }; }; +class TestStaticAttributeClass { + private: + + public: + inline static int staticIntValue; + inline static const int staticConstIntValue = 20; + inline static float staticFloatValue; + inline static double staticDoubleValue; + inline static bool staticBoolValue; +}; + class TestConstructorClass { private: @@ -147,6 +158,63 @@ class TestMethodClass { TestObjectClass getValueObject() { return refObject02; }; }; +class TestStaticMethodClass { + private: + inline static int intParam; + inline static int intParam2; + inline static float floatParam; + inline static float floatParam2; + inline static bool boolParam; + inline static string strParam; + inline static const TestObjectClass* pointerObject01 = NULL; + inline static TestObjectClass* pointerObject02 = NULL; + inline static TestObjectClass refObject01; + inline static TestObjectClass refObject02; + public: + static void setMethod01(int intParam) { + TestStaticMethodClass::intParam = intParam; + }; + static void setMethod02(float floatParam, bool boolParam) { + TestStaticMethodClass::floatParam = floatParam; + TestStaticMethodClass::boolParam = boolParam; + }; + static void setMethod03(int intParam, int intParam2, float floatParam, float floatParam2, bool boolParam = true) { + TestStaticMethodClass::intParam = intParam; + TestStaticMethodClass::intParam2 = intParam2; + TestStaticMethodClass::floatParam = floatParam; + TestStaticMethodClass::floatParam2 = floatParam2; + TestStaticMethodClass::boolParam = boolParam; + }; + static void setMethod04(int intParam, int* intArraySize2, float* floatArraySize2) { + TestStaticMethodClass::intParam = intParam; + intArraySize2[0] = 1; + intArraySize2[1] = 2; + floatArraySize2[0] = 3.1; + floatArraySize2[1] = 4.2; + }; + static void setMethod05(const char* strParam) { + TestStaticMethodClass::strParam = strParam; + }; + static void setMethod06(const TestObjectClass* pointerObject01, TestObjectClass* pointerObject02, const TestObjectClass& refObject01, TestObjectClass& refObject02) { + TestStaticMethodClass::pointerObject01 = pointerObject01; + TestStaticMethodClass::pointerObject02 = pointerObject02; + TestStaticMethodClass::refObject01 = refObject01; + TestStaticMethodClass::refObject02 = refObject02; + }; + + static int getIntParam() { return TestStaticMethodClass::intParam; }; + static int getIntParam2() { return TestStaticMethodClass::intParam2; }; + static float getFloatParam() { return TestStaticMethodClass::floatParam; }; + static float getFloatParam2() { return TestStaticMethodClass::floatParam2; }; + static bool getBoolParam() { return TestStaticMethodClass::boolParam; }; + static const char* getStrParam() { return TestStaticMethodClass::strParam.c_str(); }; + static const TestObjectClass* getPointerObject01() { return TestStaticMethodClass::pointerObject01; }; + static TestObjectClass* getPointerObject02() { return TestStaticMethodClass::pointerObject02; }; + static const TestObjectClass& getRefObject01() { return TestStaticMethodClass::refObject01; }; + static TestObjectClass& getRefObject02() { return TestStaticMethodClass::refObject02; }; + static TestObjectClass getValueObject() { return TestStaticMethodClass::refObject02; }; +}; + class TestEnumClass { private: ParamData data; From 4475c1c95645076c9597b6e3753e3784b5980b3a Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 14 Aug 2024 10:12:06 -0300 Subject: [PATCH 051/186] add callback --- .../lib/lib-build/src/main/cpp/exampleLib.idl | 38 +++++++++++ .../main/cpp/source/exampleLib/src/TestLib.h | 67 +++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/example/lib/lib-build/src/main/cpp/exampleLib.idl b/example/lib/lib-build/src/main/cpp/exampleLib.idl index 41d1114d..ac06af9e 100644 --- a/example/lib/lib-build/src/main/cpp/exampleLib.idl +++ b/example/lib/lib-build/src/main/cpp/exampleLib.idl @@ -90,6 +90,44 @@ interface TestStaticMethodClass { [Value] static TestObjectClass getValueObject(); }; +interface CallbackClass { + [Const] void onVoidCallback([Ref] TestObjectClass refData, TestObjectClass pointerData); + [Const] long onIntCallback(long intParam01, long intParam02); + [Const] float onFloatCallback(float floatParam01, float floatParam02); + [Const] boolean onBoolCallback(boolean boolParam); + [Const] void onStringCallback([Const] DOMString strParam); +}; + +[JSImplementation="CallbackClass"] +interface CallbackClassImpl { + void CallbackClassImpl(); +}; +CallbackClassImpl implements CallbackClass; + +interface DefaultCallbackClass { + void DefaultCallbackClass(); +}; +DefaultCallbackClass implements CallbackClass; + +interface TestCallbackClass { + void TestCallbackClass(); + + attribute long intParam01; + attribute long intParam02; + attribute float floatParam01; + attribute float floatParam02; + attribute boolean boolParam; + [Value] attribute TestObjectClass valueObject; + attribute TestObjectClass pointerObject; + [Value] attribute IDLString strParam; + + void callVoidCallback(CallbackClass callback); + void callIntCallback(CallbackClass callback); + void callFloatCallback(CallbackClass callback); + void callBoolCallback(CallbackClass callback); + void callStringCallback(CallbackClass callback); +}; + enum TestEnumWithinClass { "TestEnumClass::e_val" }; diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h index d9134193..41f5c446 100644 --- a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h @@ -215,6 +215,73 @@ class TestStaticMethodClass { static TestObjectClass getValueObject() { return TestStaticMethodClass::refObject02; }; }; +class CallbackClass +{ +public: + virtual ~CallbackClass() {} + + virtual void onVoidCallback(TestObjectClass& refData, TestObjectClass* pointerData) const = 0; + virtual int onIntCallback(int intParam01, int intParam02) const = 0; + virtual float onFloatCallback(float floatParam01, float Param02) const = 0; + virtual bool onBoolCallback(bool boolParam) const = 0; + virtual void onStringCallback(const char* strParam) const = 0; +}; + +class DefaultCallbackClass : public CallbackClass +{ +public: + DefaultCallbackClass() { + }; + + virtual void onVoidCallback(TestObjectClass& refData, TestObjectClass* pointerData) const { + refData.intValue = 7; + refData.floatValue = 7.77; + pointerData->intValue = 10; + pointerData->floatValue = 10.77; + } + virtual int onIntCallback(int intParam01, int intParam02) const { + return intParam01 - intParam02; + } + virtual float onFloatCallback(float floatParam01, float floatParam02) const { + return floatParam01 + floatParam02; + } + virtual bool onBoolCallback(bool boolParam) const { + return !boolParam; + } + virtual void onStringCallback(const char* strParam) const { + cout << "strParam: " << strParam << endl; + } +}; + +class TestCallbackClass { + private: + public: + int intParam01; + int intParam02; + float floatParam01; + float floatParam02; + bool boolParam; + string strParam; + TestObjectClass valueObject; + TestObjectClass* pointerObject; + + void callVoidCallback(CallbackClass* callback) { + callback->onVoidCallback(valueObject, pointerObject); + }; + int callIntCallback(CallbackClass* callback) { + return callback->onIntCallback(intParam01, intParam02); + }; + int callFloatCallback(CallbackClass* callback) { + return callback->onFloatCallback(floatParam01, floatParam02); + }; + bool callBoolCallback(CallbackClass* callback) { + return callback->onBoolCallback(boolParam); + }; + void callStringCallback(CallbackClass* callback) { + callback->onStringCallback(strParam.c_str()); + }; +}; + class TestEnumClass { private: ParamData data; From 5cf9196ac1ac945937e5b3b01ce27e795769b401 Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 14 Aug 2024 10:36:51 -0300 Subject: [PATCH 052/186] cpp class improvements --- .../lib/lib-build/src/main/cpp/exampleLib.idl | 102 ++++---- .../main/cpp/source/exampleLib/src/TestLib.h | 229 +++++++++--------- 2 files changed, 165 insertions(+), 166 deletions(-) diff --git a/example/lib/lib-build/src/main/cpp/exampleLib.idl b/example/lib/lib-build/src/main/cpp/exampleLib.idl index ac06af9e..4654cf8c 100644 --- a/example/lib/lib-build/src/main/cpp/exampleLib.idl +++ b/example/lib/lib-build/src/main/cpp/exampleLib.idl @@ -1,7 +1,7 @@ interface TestObjectClass { void TestObjectClass(); - attribute long intValue; - attribute float floatValue; + attribute long intValue01; + attribute float floatValue01; }; interface TestAttributeArrayClass { @@ -16,51 +16,51 @@ interface TestAttributeArrayClass { interface TestAttributeClass { void TestAttributeClass(); - readonly attribute long readOnlyIntValue; - attribute long intValue; - attribute float floatValue; - attribute double doubleValue; - attribute boolean boolValue; - attribute any voidPointer; + readonly attribute long readOnlyIntValue01; + attribute long intValue01; + attribute float floatValue01; + attribute double doubleValue01; + attribute boolean boolValue01; + [Value] attribute IDLString strValue01; + attribute any voidPointer01; [Value] attribute TestObjectClass valueObject; attribute TestObjectClass pointerObject; attribute TestObjectClass nullPointerObject; - [Value] attribute IDLString strParam; }; [NoDelete] interface TestStaticAttributeClass { - static attribute long staticIntValue; - static readonly attribute long staticConstIntValue; - static attribute float staticFloatValue; - static attribute double staticDoubleValue; - static attribute boolean staticBoolValue; + static attribute long staticIntValue01; + static readonly attribute long staticConstIntValue01; + static attribute float staticFloatValue01; + static attribute double staticDoubleValue01; + static attribute boolean staticBoolValue01; }; interface TestConstructorClass { - [Value] attribute IDLString strParam; + [Value] attribute IDLString strValue01; - void TestConstructorClass(long intParam); - void TestConstructorClass(float floatParam, [Const] DOMString strParam); - void TestConstructorClass(long intParam, long intParam2, float floatParam, float floatParam2, optional boolean boolParam); - void TestConstructorClass(long intParam, long[] intArray, float[] floatArray); + void TestConstructorClass(long intValue01); + void TestConstructorClass(float floatValue, [Const] DOMString strValue01); + void TestConstructorClass(long intValue01, long intValue02, float floatValue01, float floatValue02, optional boolean boolValue01); + void TestConstructorClass(long intValue01, long[] intArray, float[] floatArray); }; interface TestMethodClass { void TestMethodClass(); - void setMethod01(long intParam); - void setMethod02(float floatParam, boolean boolParam); - void setMethod03(long intParam, long intParam2, float floatParam, float floatParam2, optional boolean boolParam); - void setMethod04(long intParam, long[] intArray, float[] floatArray); - void setMethod05([Const] DOMString strParam); + void setMethod01(long intValue01); + void setMethod02(float floatValue01, boolean boolValue01); + void setMethod03(long intValue01, long intValue02, float floatValue01, float floatValue02, optional boolean boolValue01); + void setMethod04(long intValue01, long[] intArray, float[] floatArray); + void setMethod05([Const] DOMString strValue01); void setMethod06([Const] TestObjectClass pointerObject01, TestObjectClass pointerObject02, [Const, Ref] TestObjectClass refObject01, [Ref] TestObjectClass refObject02); - long getIntParam(); - long getIntParam2(); - float getFloatParam(); - float getFloatParam2(); - float getBoolParam(); - [Const, Value] IDLStringView getStrParam(); + long getIntValue01(); + long getIntValue02(); + float getFloatValue01(); + float getFloatValue02(); + float getBoolValue01(); + [Const, Value] IDLStringView getStrValue01(); [Const] TestObjectClass getPointerObject01(); TestObjectClass getPointerObject02(); [Const, Ref] TestObjectClass getRefObject01(); @@ -70,19 +70,19 @@ interface TestMethodClass { [NoDelete] interface TestStaticMethodClass { - static void setMethod01(long intParam); - static void setMethod02(float floatParam, boolean boolParam); - static void setMethod03(long intParam, long intParam2, float floatParam, float floatParam2, optional boolean boolParam); - static void setMethod04(long intParam, long[] intArray, float[] floatArray); - static void setMethod05([Const] DOMString strParam); + static void setMethod01(long intValue01); + static void setMethod02(float floatValue01, boolean boolValue01); + static void setMethod03(long intValue01, long intValue02, float floatValue01, float floatValue02, optional boolean boolValue01); + static void setMethod04(long intValue01, long[] intArray, float[] floatArray); + static void setMethod05([Const] DOMString strValue01); static void setMethod06([Const] TestObjectClass pointerObject01, TestObjectClass pointerObject02, [Const, Ref] TestObjectClass refObject01, [Ref] TestObjectClass refObject02); - static long getIntParam(); - static long getIntParam2(); - static float getFloatParam(); - static float getFloatParam2(); - static float getBoolParam(); - [Const, Value] static IDLStringView getStrParam(); + static long getIntValue01(); + static long getIntValue02(); + static float getFloatValue01(); + static float getFloatValue02(); + static float getBoolValue01(); + [Const, Value] static IDLStringView getStrValue01(); [Const] static TestObjectClass getPointerObject01(); static TestObjectClass getPointerObject02(); [Const, Ref] static TestObjectClass getRefObject01(); @@ -92,10 +92,10 @@ interface TestStaticMethodClass { interface CallbackClass { [Const] void onVoidCallback([Ref] TestObjectClass refData, TestObjectClass pointerData); - [Const] long onIntCallback(long intParam01, long intParam02); - [Const] float onFloatCallback(float floatParam01, float floatParam02); - [Const] boolean onBoolCallback(boolean boolParam); - [Const] void onStringCallback([Const] DOMString strParam); + [Const] long onIntCallback(long intValue01, long intValue02); + [Const] float onFloatCallback(float floatValue01, float floatValue02); + [Const] boolean onBoolCallback(boolean boolValue01); + [Const] void onStringCallback([Const] DOMString strValue01); }; [JSImplementation="CallbackClass"] @@ -112,14 +112,14 @@ DefaultCallbackClass implements CallbackClass; interface TestCallbackClass { void TestCallbackClass(); - attribute long intParam01; - attribute long intParam02; - attribute float floatParam01; - attribute float floatParam02; - attribute boolean boolParam; + attribute long intValue01; + attribute long intValue02; + attribute float floatValue01; + attribute float floatValue02; + attribute boolean boolValue01; + [Value] attribute IDLString strValue01; [Value] attribute TestObjectClass valueObject; attribute TestObjectClass pointerObject; - [Value] attribute IDLString strParam; void callVoidCallback(CallbackClass callback); void callIntCallback(CallbackClass callback); diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h index 41f5c446..5b259fab 100644 --- a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h @@ -11,8 +11,8 @@ class TestObjectClass { private: public: - int intValue; - float floatValue; + int intValue01; + float floatValue01; }; class TestAttributeArrayClass { @@ -31,18 +31,18 @@ class TestAttributeClass { private: public: - const int readOnlyIntValue; - int intValue; - float floatValue; - double doubleValue; - bool boolValue; - void* voidPointer; + const int readOnlyIntValue01; + int intValue01; + float floatValue01; + double doubleValue01; + bool boolValue01; + string strValue01; + void* voidPointer01; TestObjectClass valueObject; TestObjectClass* pointerObject; TestObjectClass* nullPointerObject; - string strParam; - TestAttributeClass(): readOnlyIntValue(7) { + TestAttributeClass(): readOnlyIntValue01(7) { pointerObject = new TestObjectClass(); nullPointerObject = NULL; }; @@ -55,41 +55,40 @@ class TestStaticAttributeClass { private: public: - inline static int staticIntValue; - inline static const int staticConstIntValue = 20; - inline static float staticFloatValue; - inline static double staticDoubleValue; - inline static bool staticBoolValue; + inline static int staticIntValue01; + inline static const int staticConstIntValue01 = 20; + inline static float staticFloatValue01; + inline static double staticDoubleValue01; + inline static bool staticBoolValue01; }; class TestConstructorClass { private: public: - int intParam; - float intParam2; - float floatParam; - float floatParam2; - bool boolParam; - string strParam; + int intValue01; + int intValue02; + float floatValue01; + float floatValue02; + bool boolValue01; + string strValue01; - TestConstructorClass(int intParam) { - this->intParam = intParam; + TestConstructorClass(int intValue01) { + this->intValue01 = intValue01; }; - TestConstructorClass(float floatParam, const char* strParam) { - this->floatParam = floatParam; - this->boolParam = boolParam; - this->strParam = strParam; + TestConstructorClass(float floatValue01, const char* strValue01) { + this->floatValue01 = floatValue01; + this->strValue01 = strValue01; }; - TestConstructorClass(int intParam, int intParam2, float floatParam, float floatParam2, bool boolParam = true) { - this->intParam = intParam; - this->intParam2 = intParam2; - this->floatParam = floatParam; - this->floatParam2 = floatParam2; - this->boolParam = boolParam; + TestConstructorClass(int intValue01, int intValue02, float floatValue01, float floatValue02, bool boolValue01 = true) { + this->intValue01 = intValue01; + this->intValue02 = intValue02; + this->floatValue01 = floatValue01; + this->floatValue02 = floatValue02; + this->boolValue01 = boolValue01; }; - TestConstructorClass(int intParam, int* intArraySize2, float* floatArraySize2) { - this->intParam = intParam; + TestConstructorClass(int intValue01, int* intArraySize2, float* floatArraySize2) { + this->intValue01 = intValue01; intArraySize2[0] = 1; intArraySize2[1] = 2; floatArraySize2[0] = 3.1; @@ -99,12 +98,12 @@ class TestConstructorClass { class TestMethodClass { private: - int intParam; - int intParam2; - float floatParam; - float floatParam2; - bool boolParam; - string strParam; + int intValue01; + int intValue02; + float floatValue01; + float floatValue02; + bool boolValue01; + string strValue01; const TestObjectClass* pointerObject01; TestObjectClass* pointerObject02; TestObjectClass refObject01; @@ -114,29 +113,29 @@ class TestMethodClass { pointerObject01 = NULL; pointerObject02 = NULL; }; - void setMethod01(int intParam) { - this->intParam = intParam; + void setMethod01(int intValue01) { + this->intValue01 = intValue01; }; - void setMethod02(float floatParam, bool boolParam) { - this->floatParam = floatParam; - this->boolParam = boolParam; + void setMethod02(float floatValue01, bool boolValue01) { + this->floatValue01 = floatValue01; + this->boolValue01 = boolValue01; }; - void setMethod03(int intParam, int intParam2, float floatParam, float floatParam2, bool boolParam = true) { - this->intParam = intParam; - this->intParam2 = intParam2; - this->floatParam = floatParam; - this->floatParam2 = floatParam2; - this->boolParam = boolParam; + void setMethod03(int intValue01, int intValue02, float floatValue01, float floatValue02, bool boolValue01 = true) { + this->intValue01 = intValue01; + this->intValue02 = intValue02; + this->floatValue01 = floatValue01; + this->floatValue02 = floatValue02; + this->boolValue01 = boolValue01; }; - void setMethod04(int intParam, int* intArraySize2, float* floatArraySize2) { - this->intParam = intParam; + void setMethod04(int intValue01, int* intArraySize2, float* floatArraySize2) { + this->intValue01 = intValue01; intArraySize2[0] = 1; intArraySize2[1] = 2; floatArraySize2[0] = 3.1; floatArraySize2[1] = 4.2; }; - void setMethod05(const char* strParam) { - this->strParam = strParam; + void setMethod05(const char* strValue01) { + this->strValue01 = strValue01; }; void setMethod06(const TestObjectClass* pointerObject01, TestObjectClass* pointerObject02, const TestObjectClass& refObject01, TestObjectClass& refObject02) { this->pointerObject01 = pointerObject01; @@ -145,12 +144,12 @@ class TestMethodClass { this->refObject02 = refObject02; }; - int getIntParam() { return intParam; }; - int getIntParam2() { return intParam2; }; - float getFloatParam() { return floatParam; }; - float getFloatParam2() { return floatParam2; }; - bool getBoolParam() { return boolParam; }; - const char* getStrParam() { return strParam.c_str(); }; + int getIntValue01() { return intValue01; }; + int getIntValue02() { return intValue02; }; + float getFloatValue01() { return floatValue01; }; + float getFloatValue02() { return floatValue02; }; + bool getBoolValue01() { return boolValue01; }; + const char* getStrValue01() { return strValue01.c_str(); }; const TestObjectClass* getPointerObject01() { return pointerObject01; }; TestObjectClass* getPointerObject02() { return pointerObject02; }; const TestObjectClass& getRefObject01() { return refObject01; }; @@ -160,40 +159,40 @@ class TestMethodClass { class TestStaticMethodClass { private: - inline static int intParam; - inline static int intParam2; - inline static float floatParam; - inline static float floatParam2; - inline static bool boolParam; - inline static string strParam; + inline static int intValue01; + inline static int intValue02; + inline static float floatValue01; + inline static float floatValue02; + inline static bool boolValue01; + inline static string strValue01; inline static const TestObjectClass* pointerObject01 = NULL; inline static TestObjectClass* pointerObject02 = NULL; inline static TestObjectClass refObject01; inline static TestObjectClass refObject02; public: - static void setMethod01(int intParam) { - TestStaticMethodClass::intParam = intParam; + static void setMethod01(int intValue01) { + TestStaticMethodClass::intValue01 = intValue01; }; - static void setMethod02(float floatParam, bool boolParam) { - TestStaticMethodClass::floatParam = floatParam; - TestStaticMethodClass::boolParam = boolParam; + static void setMethod02(float floatValue01, bool boolValue01) { + TestStaticMethodClass::floatValue01 = floatValue01; + TestStaticMethodClass::boolValue01 = boolValue01; }; - static void setMethod03(int intParam, int intParam2, float floatParam, float floatParam2, bool boolParam = true) { - TestStaticMethodClass::intParam = intParam; - TestStaticMethodClass::intParam2 = intParam2; - TestStaticMethodClass::floatParam = floatParam; - TestStaticMethodClass::floatParam2 = floatParam2; - TestStaticMethodClass::boolParam = boolParam; + static void setMethod03(int intValue01, int intValue02, float floatValue01, float floatValue02, bool boolValue01 = true) { + TestStaticMethodClass::intValue01 = intValue01; + TestStaticMethodClass::intValue02 = intValue02; + TestStaticMethodClass::floatValue01 = floatValue01; + TestStaticMethodClass::floatValue02 = floatValue02; + TestStaticMethodClass::boolValue01 = boolValue01; }; - static void setMethod04(int intParam, int* intArraySize2, float* floatArraySize2) { - TestStaticMethodClass::intParam = intParam; + static void setMethod04(int intValue01, int* intArraySize2, float* floatArraySize2) { + TestStaticMethodClass::intValue01 = intValue01; intArraySize2[0] = 1; intArraySize2[1] = 2; floatArraySize2[0] = 3.1; floatArraySize2[1] = 4.2; }; - static void setMethod05(const char* strParam) { - TestStaticMethodClass::strParam = strParam; + static void setMethod05(const char* strValue01) { + TestStaticMethodClass::strValue01 = strValue01; }; static void setMethod06(const TestObjectClass* pointerObject01, TestObjectClass* pointerObject02, const TestObjectClass& refObject01, TestObjectClass& refObject02) { TestStaticMethodClass::pointerObject01 = pointerObject01; @@ -202,12 +201,12 @@ class TestStaticMethodClass { TestStaticMethodClass::refObject02 = refObject02; }; - static int getIntParam() { return TestStaticMethodClass::intParam; }; - static int getIntParam2() { return TestStaticMethodClass::intParam2; }; - static float getFloatParam() { return TestStaticMethodClass::floatParam; }; - static float getFloatParam2() { return TestStaticMethodClass::floatParam2; }; - static bool getBoolParam() { return TestStaticMethodClass::boolParam; }; - static const char* getStrParam() { return TestStaticMethodClass::strParam.c_str(); }; + static int getIntValue01() { return TestStaticMethodClass::intValue01; }; + static int getIntValue02() { return TestStaticMethodClass::intValue02; }; + static float getFloatValue01() { return TestStaticMethodClass::floatValue01; }; + static float getFloatValue02() { return TestStaticMethodClass::floatValue02; }; + static bool getBoolValue01() { return TestStaticMethodClass::boolValue01; }; + static const char* getStrValue01() { return TestStaticMethodClass::strValue01.c_str(); }; static const TestObjectClass* getPointerObject01() { return TestStaticMethodClass::pointerObject01; }; static TestObjectClass* getPointerObject02() { return TestStaticMethodClass::pointerObject02; }; static const TestObjectClass& getRefObject01() { return TestStaticMethodClass::refObject01; }; @@ -221,10 +220,10 @@ class CallbackClass virtual ~CallbackClass() {} virtual void onVoidCallback(TestObjectClass& refData, TestObjectClass* pointerData) const = 0; - virtual int onIntCallback(int intParam01, int intParam02) const = 0; - virtual float onFloatCallback(float floatParam01, float Param02) const = 0; - virtual bool onBoolCallback(bool boolParam) const = 0; - virtual void onStringCallback(const char* strParam) const = 0; + virtual int onIntCallback(int intValue01, int intValue02) const = 0; + virtual float onFloatCallback(float floatValue01, float Value02) const = 0; + virtual bool onBoolCallback(bool boolValue01) const = 0; + virtual void onStringCallback(const char* strValue01) const = 0; }; class DefaultCallbackClass : public CallbackClass @@ -234,34 +233,34 @@ class DefaultCallbackClass : public CallbackClass }; virtual void onVoidCallback(TestObjectClass& refData, TestObjectClass* pointerData) const { - refData.intValue = 7; - refData.floatValue = 7.77; - pointerData->intValue = 10; - pointerData->floatValue = 10.77; + refData.intValue01 = 7; + refData.floatValue01 = 7.77; + pointerData->intValue01 = 10; + pointerData->floatValue01 = 10.77; } - virtual int onIntCallback(int intParam01, int intParam02) const { - return intParam01 - intParam02; + virtual int onIntCallback(int intValue01, int intValue02) const { + return intValue01 - intValue02; } - virtual float onFloatCallback(float floatParam01, float floatParam02) const { - return floatParam01 + floatParam02; + virtual float onFloatCallback(float floatValue01, float floatValue02) const { + return floatValue01 + floatValue02; } - virtual bool onBoolCallback(bool boolParam) const { - return !boolParam; + virtual bool onBoolCallback(bool boolValue01) const { + return !boolValue01; } - virtual void onStringCallback(const char* strParam) const { - cout << "strParam: " << strParam << endl; + virtual void onStringCallback(const char* strValue01) const { + cout << "strValue01: " << strValue01 << endl; } }; class TestCallbackClass { private: public: - int intParam01; - int intParam02; - float floatParam01; - float floatParam02; - bool boolParam; - string strParam; + int intValue01; + int intValue02; + float floatValue01; + float floatValue02; + bool boolValue01; + string strValue01; TestObjectClass valueObject; TestObjectClass* pointerObject; @@ -269,16 +268,16 @@ class TestCallbackClass { callback->onVoidCallback(valueObject, pointerObject); }; int callIntCallback(CallbackClass* callback) { - return callback->onIntCallback(intParam01, intParam02); + return callback->onIntCallback(intValue01, intValue02); }; int callFloatCallback(CallbackClass* callback) { - return callback->onFloatCallback(floatParam01, floatParam02); + return callback->onFloatCallback(floatValue01, floatValue02); }; bool callBoolCallback(CallbackClass* callback) { - return callback->onBoolCallback(boolParam); + return callback->onBoolCallback(boolValue01); }; void callStringCallback(CallbackClass* callback) { - callback->onStringCallback(strParam.c_str()); + callback->onStringCallback(strValue01.c_str()); }; }; From 8103a8af980dc1d25b4a48e0c6068b1e5539f202 Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 14 Aug 2024 13:59:32 -0300 Subject: [PATCH 053/186] Fix convert long to int for teavm --- .../xpenatan/jparser/teavm/TeaVMCodeParser.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index 64681938..09cd601c 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -751,17 +751,19 @@ private MethodDeclaration getNativeMethod(ClassOrInterfaceDeclaration classDecla if(arguments.size() > 0) { for(int i = 0; i < arguments.size(); i++) { Expression expression = arguments.get(i); + if(expression.isMethodCallExpr() || expression.isEnclosedExpr()) { + paramTypes.add("long"); + continue; + } + else if(expression.isLambdaExpr()) { + continue; + } ResolvedType resolvedType = null; try { resolvedType = expression.calculateResolvedType(); } catch(Throwable t) { - - if(t instanceof UnsolvedSymbolException) { - UnsolvedSymbolException unE = (UnsolvedSymbolException)t; - String name = unE.getName(); - paramTypes.add(name); - } + t.printStackTrace(); continue; } String type = null; From ee541147ebbf516065f2ec3eaed86ee4210d07ba Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 14 Aug 2024 13:59:50 -0300 Subject: [PATCH 054/186] remove other demo --- ...app-test_desktop [run-app-desktop].run.xml | 24 -- ...test_lib-build [build_project_all].run.xml | 24 -- build.gradle.kts | 2 - example/app-test/android/build.gradle.kts | 76 ---- example/app-test/android/proguard-rules.pro | 21 - .../android/src/main/AndroidManifest.xml | 19 - .../example/myapplication/MainActivity.kt | 16 - .../drawable-v24/ic_launcher_foreground.xml | 31 -- .../res/drawable/ic_launcher_background.xml | 74 ---- .../src/main/res/layout/activity_main.xml | 10 - .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 - .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 - .../res/mipmap-anydpi-v33/ic_launcher.xml | 6 - .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 1404 -> 0 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 2898 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 982 -> 0 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 1772 -> 0 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 1900 -> 0 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 3918 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 2884 -> 0 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 5914 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 3844 -> 0 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 7778 -> 0 bytes .../android/src/main/res/values/colors.xml | 10 - .../android/src/main/res/values/strings.xml | 3 - example/app-test/core/build.gradle.kts | 5 - .../jparser/example/app/AppTestLib.java | 375 ------------------ .../app-test/desktop/assets/data/badlogic.jpg | Bin 68465 -> 0 bytes example/app-test/desktop/build.gradle.kts | 22 - .../xpenatan/jparser/example/app/Main.java | 12 - example/app-test/teavm/build.gradle.kts | 34 -- .../app-test/teavm/src/main/java/Build.java | 21 - .../teavm/src/main/java/TeaVMLauncher.java | 13 - example/lib-ext/ext-base/build.gradle.kts | 3 - .../src/main/java/com.lib.ext/CustomLib.java | 7 - example/lib-ext/ext-build/build.gradle.kts | 12 - .../lib-ext/ext-build/src/main/cpp/ExtLib.idl | 3 - .../main/cpp/cpp-source/custom/CustomLib.cpp | 1 - .../main/cpp/cpp-source/custom/CustomLib.h | 14 - .../ext-build/src/main/java/BuildExtCode.java | 71 ---- example/lib-ext/ext-core/build.gradle.kts | 14 - example/lib-ext/ext-teavm/build.gradle.kts | 17 - .../resources/META-INF/gdx-teavm.properties | 0 .../main/resources/META-INF/teavm.properties | 1 - example/lib-test/lib-android/build.gradle.kts | 31 -- example/lib-test/lib-base/build.gradle.kts | 10 - .../src/main/java/lib/test/TestLibLoader.java | 42 -- example/lib-test/lib-build/build.gradle.kts | 98 ----- .../src/main/cpp/custom/CustomCode.cpp | 1 - .../src/main/cpp/custom/CustomCode.h | 4 - .../src/main/cpp/source/testLib/src/test.cpp | 15 - .../src/main/cpp/source/testLib/src/test.h | 243 ------------ .../lib-test/lib-build/src/main/cpp/test.idl | 212 ---------- .../lib-build/src/main/java/BuildLib.java | 187 --------- example/lib-test/lib-core/build.gradle.kts | 19 - example/lib-test/lib-desktop/build.gradle.kts | 34 -- example/lib-test/lib-teavm/build.gradle.kts | 35 -- .../resources/META-INF/gdx-teavm.properties | 0 .../main/resources/META-INF/teavm.properties | 1 - settings.gradle.kts | 13 - 60 files changed, 1896 deletions(-) delete mode 100644 .run/jParser_example_app-test_desktop [run-app-desktop].run.xml delete mode 100644 .run/jParser_example_lib-test_lib-build [build_project_all].run.xml delete mode 100644 example/app-test/android/build.gradle.kts delete mode 100644 example/app-test/android/proguard-rules.pro delete mode 100644 example/app-test/android/src/main/AndroidManifest.xml delete mode 100644 example/app-test/android/src/main/kotlin/lib.test.android/example/myapplication/MainActivity.kt delete mode 100644 example/app-test/android/src/main/res/drawable-v24/ic_launcher_foreground.xml delete mode 100644 example/app-test/android/src/main/res/drawable/ic_launcher_background.xml delete mode 100644 example/app-test/android/src/main/res/layout/activity_main.xml delete mode 100644 example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml delete mode 100644 example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml delete mode 100644 example/app-test/android/src/main/res/mipmap-anydpi-v33/ic_launcher.xml delete mode 100644 example/app-test/android/src/main/res/mipmap-hdpi/ic_launcher.webp delete mode 100644 example/app-test/android/src/main/res/mipmap-hdpi/ic_launcher_round.webp delete mode 100644 example/app-test/android/src/main/res/mipmap-mdpi/ic_launcher.webp delete mode 100644 example/app-test/android/src/main/res/mipmap-mdpi/ic_launcher_round.webp delete mode 100644 example/app-test/android/src/main/res/mipmap-xhdpi/ic_launcher.webp delete mode 100644 example/app-test/android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp delete mode 100644 example/app-test/android/src/main/res/mipmap-xxhdpi/ic_launcher.webp delete mode 100644 example/app-test/android/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp delete mode 100644 example/app-test/android/src/main/res/mipmap-xxxhdpi/ic_launcher.webp delete mode 100644 example/app-test/android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp delete mode 100644 example/app-test/android/src/main/res/values/colors.xml delete mode 100644 example/app-test/android/src/main/res/values/strings.xml delete mode 100644 example/app-test/core/build.gradle.kts delete mode 100644 example/app-test/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTestLib.java delete mode 100644 example/app-test/desktop/assets/data/badlogic.jpg delete mode 100644 example/app-test/desktop/build.gradle.kts delete mode 100644 example/app-test/desktop/src/main/java/com/github/xpenatan/jparser/example/app/Main.java delete mode 100644 example/app-test/teavm/build.gradle.kts delete mode 100644 example/app-test/teavm/src/main/java/Build.java delete mode 100644 example/app-test/teavm/src/main/java/TeaVMLauncher.java delete mode 100644 example/lib-ext/ext-base/build.gradle.kts delete mode 100644 example/lib-ext/ext-base/src/main/java/com.lib.ext/CustomLib.java delete mode 100644 example/lib-ext/ext-build/build.gradle.kts delete mode 100644 example/lib-ext/ext-build/src/main/cpp/ExtLib.idl delete mode 100644 example/lib-ext/ext-build/src/main/cpp/cpp-source/custom/CustomLib.cpp delete mode 100644 example/lib-ext/ext-build/src/main/cpp/cpp-source/custom/CustomLib.h delete mode 100644 example/lib-ext/ext-build/src/main/java/BuildExtCode.java delete mode 100644 example/lib-ext/ext-core/build.gradle.kts delete mode 100644 example/lib-ext/ext-teavm/build.gradle.kts delete mode 100644 example/lib-ext/ext-teavm/src/main/resources/META-INF/gdx-teavm.properties delete mode 100644 example/lib-ext/ext-teavm/src/main/resources/META-INF/teavm.properties delete mode 100644 example/lib-test/lib-android/build.gradle.kts delete mode 100644 example/lib-test/lib-base/build.gradle.kts delete mode 100644 example/lib-test/lib-base/src/main/java/lib/test/TestLibLoader.java delete mode 100644 example/lib-test/lib-build/build.gradle.kts delete mode 100644 example/lib-test/lib-build/src/main/cpp/custom/CustomCode.cpp delete mode 100644 example/lib-test/lib-build/src/main/cpp/custom/CustomCode.h delete mode 100644 example/lib-test/lib-build/src/main/cpp/source/testLib/src/test.cpp delete mode 100644 example/lib-test/lib-build/src/main/cpp/source/testLib/src/test.h delete mode 100644 example/lib-test/lib-build/src/main/cpp/test.idl delete mode 100644 example/lib-test/lib-build/src/main/java/BuildLib.java delete mode 100644 example/lib-test/lib-core/build.gradle.kts delete mode 100644 example/lib-test/lib-desktop/build.gradle.kts delete mode 100644 example/lib-test/lib-teavm/build.gradle.kts delete mode 100644 example/lib-test/lib-teavm/src/main/resources/META-INF/gdx-teavm.properties delete mode 100644 example/lib-test/lib-teavm/src/main/resources/META-INF/teavm.properties diff --git a/.run/jParser_example_app-test_desktop [run-app-desktop].run.xml b/.run/jParser_example_app-test_desktop [run-app-desktop].run.xml deleted file mode 100644 index 19a44750..00000000 --- a/.run/jParser_example_app-test_desktop [run-app-desktop].run.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - true - true - false - false - - - \ No newline at end of file diff --git a/.run/jParser_example_lib-test_lib-build [build_project_all].run.xml b/.run/jParser_example_lib-test_lib-build [build_project_all].run.xml deleted file mode 100644 index e47fc935..00000000 --- a/.run/jParser_example_lib-test_lib-build [build_project_all].run.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - true - true - false - false - - - \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 62b24af5..c69762e5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -42,8 +42,6 @@ allprojects() { configure(allprojects - project(":example:app:android") - project(":example:lib:lib-android") - - project(":example:lib-test:lib-android") - - project(":example:app-test:android") ) { apply { plugin("java") diff --git a/example/app-test/android/build.gradle.kts b/example/app-test/android/build.gradle.kts deleted file mode 100644 index e973e3ce..00000000 --- a/example/app-test/android/build.gradle.kts +++ /dev/null @@ -1,76 +0,0 @@ -plugins { - id("com.android.application") - id("kotlin-android") -} - -group = "lib.test.android" - -android { - namespace = "lib.test.android" - compileSdk = 33 - - defaultConfig { - applicationId = "lib.test.android" - minSdk = 24 - targetSdk = 33 - versionCode = 1 - versionName = "1.0" - } - - sourceSets { - named("main") { -// java.srcDirs("src/main/kotlin") -// assets.srcDirs(project.file("../assets")) - jniLibs.srcDirs("libs") - } - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - kotlinOptions { - jvmTarget = "11" - } -} -val natives: Configuration by configurations.creating - -dependencies { - coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3") - implementation("com.badlogicgames.gdx:gdx:${LibExt.gdxVersion}") - implementation("com.badlogicgames.gdx:gdx-backend-android:${LibExt.gdxVersion}") - natives("com.badlogicgames.gdx:gdx-platform:${LibExt.gdxVersion}:natives-armeabi-v7a") - natives("com.badlogicgames.gdx:gdx-platform:${LibExt.gdxVersion}:natives-arm64-v8a") - natives("com.badlogicgames.gdx:gdx-platform:${LibExt.gdxVersion}:natives-x86_64") - natives("com.badlogicgames.gdx:gdx-platform:${LibExt.gdxVersion}:natives-x86") - - implementation(project(":example:app-test:core")) - implementation(project(":example:lib-test:lib-android")) -} - - -tasks.register("copyAndroidNatives") { - doFirst { - natives.files.forEach { jar -> - val outputDir = file("libs/" + jar.nameWithoutExtension.substringAfterLast("natives-")) - outputDir.mkdirs() - copy { - from(zipTree(jar)) - into(outputDir) - include("*.so") - } - } - } -} - -tasks.whenTaskAdded { - if ("package" in name) { - dependsOn("copyAndroidNatives") - } -} \ No newline at end of file diff --git a/example/app-test/android/proguard-rules.pro b/example/app-test/android/proguard-rules.pro deleted file mode 100644 index 481bb434..00000000 --- a/example/app-test/android/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/example/app-test/android/src/main/AndroidManifest.xml b/example/app-test/android/src/main/AndroidManifest.xml deleted file mode 100644 index bac4e34d..00000000 --- a/example/app-test/android/src/main/AndroidManifest.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/example/app-test/android/src/main/kotlin/lib.test.android/example/myapplication/MainActivity.kt b/example/app-test/android/src/main/kotlin/lib.test.android/example/myapplication/MainActivity.kt deleted file mode 100644 index d1c1c501..00000000 --- a/example/app-test/android/src/main/kotlin/lib.test.android/example/myapplication/MainActivity.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.example.myapplication - -import android.os.Bundle -import com.badlogic.gdx.backends.android.AndroidApplication -import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration -import com.github.xpenatan.jparser.example.app.AppTest - -class MainActivity : AndroidApplication() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - initialize(AppTest(), AndroidApplicationConfiguration().apply { - // Configure your application here. - useImmersiveMode = true // Recommended, but not required. - }) - } -} \ No newline at end of file diff --git a/example/app-test/android/src/main/res/drawable-v24/ic_launcher_foreground.xml b/example/app-test/android/src/main/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index 09b36162..00000000 --- a/example/app-test/android/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/example/app-test/android/src/main/res/drawable/ic_launcher_background.xml b/example/app-test/android/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 9c9f7c82..00000000 --- a/example/app-test/android/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/example/app-test/android/src/main/res/layout/activity_main.xml b/example/app-test/android/src/main/res/layout/activity_main.xml deleted file mode 100644 index 18e36833..00000000 --- a/example/app-test/android/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - \ No newline at end of file diff --git a/example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index bbd3e021..00000000 --- a/example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index bbd3e021..00000000 --- a/example/app-test/android/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/example/app-test/android/src/main/res/mipmap-anydpi-v33/ic_launcher.xml b/example/app-test/android/src/main/res/mipmap-anydpi-v33/ic_launcher.xml deleted file mode 100644 index 50ec8862..00000000 --- a/example/app-test/android/src/main/res/mipmap-anydpi-v33/ic_launcher.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/example/app-test/android/src/main/res/mipmap-hdpi/ic_launcher.webp b/example/app-test/android/src/main/res/mipmap-hdpi/ic_launcher.webp deleted file mode 100644 index c209e78ecd372343283f4157dcfd918ec5165bb3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1404 zcmV-?1%vuhNk&F=1pok7MM6+kP&il$0000G0000-002h-06|PpNX!5L00Dqw+t%{r zzW2vH!KF=w&cMnnN@{whkTw+#mAh0SV?YL=)3MimFYCWp#fpdtz~8$hD5VPuQgtcN zXl<@<#Cme5f5yr2h%@8TWh?)bSK`O z^Z@d={gn7J{iyxL_y_%J|L>ep{dUxUP8a{byupH&!UNR*OutO~0{*T4q5R6@ApLF! z5{w?Z150gC7#>(VHFJZ-^6O@PYp{t!jH(_Z*nzTK4 zkc{fLE4Q3|mA2`CWQ3{8;gxGizgM!zccbdQoOLZc8hThi-IhN90RFT|zlxh3Ty&VG z?Fe{#9RrRnxzsu|Lg2ddugg7k%>0JeD+{XZ7>Z~{=|M+sh1MF7~ zz>To~`~LVQe1nNoR-gEzkpe{Ak^7{{ZBk2i_<+`Bq<^GB!RYG+z)h;Y3+<{zlMUYd zrd*W4w&jZ0%kBuDZ1EW&KLpyR7r2=}fF2%0VwHM4pUs}ZI2egi#DRMYZPek*^H9YK zay4Iy3WXFG(F14xYsoDA|KXgGc5%2DhmQ1gFCkrgHBm!lXG8I5h*uf{rn48Z!_@ z4Bk6TJAB2CKYqPjiX&mWoW>OPFGd$wqroa($ne7EUK;#3VYkXaew%Kh^3OrMhtjYN?XEoY`tRPQsAkH-DSL^QqyN0>^ zmC>{#F14jz4GeW{pJoRpLFa_*GI{?T93^rX7SPQgT@LbLqpNA}<@2wH;q493)G=1Y z#-sCiRNX~qf3KgiFzB3I>4Z%AfS(3$`-aMIBU+6?gbgDb!)L~A)je+;fR0jWLL-Fu z4)P{c7{B4Hp91&%??2$v9iRSFnuckHUm}or9seH6 z>%NbT+5*@L5(I9j@06@(!{ZI?U0=pKn8uwIg&L{JV14+8s2hnvbRrU|hZCd}IJu7*;;ECgO%8_*W Kmw_-CKmY()leWbG diff --git a/example/app-test/android/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/example/app-test/android/src/main/res/mipmap-hdpi/ic_launcher_round.webp deleted file mode 100644 index b2dfe3d1ba5cf3ee31b3ecc1ced89044a1f3b7a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2898 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 diff --git a/example/app-test/android/src/main/res/mipmap-mdpi/ic_launcher.webp b/example/app-test/android/src/main/res/mipmap-mdpi/ic_launcher.webp deleted file mode 100644 index 4f0f1d64e58ba64d180ce43ee13bf9a17835fbca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 982 zcmV;{11bDcNk&G_0{{S5MM6+kP&il$0000G0000l001ul06|PpNU8t;00Dqo+t#w^ z^1csucXz7-Qrhzl9HuHB%l>&>1tG2^vb*E&k^T3$FG1eQZ51g$uv4V+kI`0<^1Z@N zk?Jjh$olyC%l>)Xq;7!>{iBj&BjJ`P&$fsCfpve_epJOBkTF?nu-B7D!hO=2ZR}

C%4 zc_9eOXvPbC4kzU8YowIA8cW~Uv|eB&yYwAObSwL2vY~UYI7NXPvf3b+c^?wcs~_t{ ze_m66-0)^{JdOMKPwjpQ@Sna!*?$wTZ~su*tNv7o!gXT!GRgivP}ec?5>l1!7<(rT zds|8x(qGc673zrvYIz;J23FG{9nHMnAuP}NpAED^laz3mAN1sy+NXK)!6v1FxQ;lh zOBLA>$~P3r4b*NcqR;y6pwyhZ3_PiDb|%n1gGjl3ZU}ujInlP{eks-#oA6>rh&g+!f`hv#_%JrgYPu z(U^&XLW^QX7F9Z*SRPpQl{B%x)_AMp^}_v~?j7 zapvHMKxSf*Mtyx8I}-<*UGn3)oHd(nn=)BZ`d$lDBwq_GL($_TPaS{UeevT(AJ`p0 z9%+hQb6z)U9qjbuXjg|dExCLjpS8$VKQ55VsIC%@{N5t{NsW)=hNGI`J=x97_kbz@ E0Of=7!TQj4N+cqN`nQhxvX7dAV-`K|Ub$-q+H-5I?Tx0g9jWxd@A|?POE8`3b8fO$T))xP* z(X?&brZw({`)WU&rdAs1iTa0x6F@PIxJ&&L|dpySV!ID|iUhjCcKz(@mE z!x@~W#3H<)4Ae(4eQJRk`Iz3<1)6^m)0b_4_TRZ+cz#eD3f8V;2r-1fE!F}W zEi0MEkTTx}8i1{`l_6vo0(Vuh0HD$I4SjZ=?^?k82R51bC)2D_{y8mi_?X^=U?2|F{Vr7s!k(AZC$O#ZMyavHhlQ7 zUR~QXuH~#o#>(b$u4?s~HLF*3IcF7023AlwAYudn0FV~|odGH^05AYPEfR)8p`i{n zwg3zPVp{+wOsxKc>)(pMupKF!Y2HoUqQ3|Yu|8lwR=?5zZuhG6J?H`bSNk_wPoM{u zSL{c@pY7+c2kck>`^q1^^gR0QB7Y?KUD{vz-uVX~;V-rW)PDcI)$_UjgVV?S?=oLR zf4}zz{#*R_{LkiJ#0RdQLNC^2Vp%JPEUvG9ra2BVZ92(p9h7Ka@!yf9(lj#}>+|u* z;^_?KWdzkM`6gqPo9;;r6&JEa)}R3X{(CWv?NvgLeOTq$cZXqf7|sPImi-7cS8DCN zGf;DVt3Am`>hH3{4-WzH43Ftx)SofNe^-#|0HdCo<+8Qs!}TZP{HH8~z5n`ExcHuT zDL1m&|DVpIy=xsLO>8k92HcmfSKhflQ0H~9=^-{#!I1g(;+44xw~=* zxvNz35vfsQE)@)Zsp*6_GjYD};Squ83<_?^SbALb{a`j<0Gn%6JY!zhp=Fg}Ga2|8 z52e1WU%^L1}15Ex0fF$e@eCT(()_P zvV?CA%#Sy08_U6VPt4EtmVQraWJX` zh=N|WQ>LgrvF~R&qOfB$!%D3cGv?;Xh_z$z7k&s4N)$WYf*k=|*jCEkO19{h_(%W4 zPuOqbCw`SeAX*R}UUsbVsgtuG?xs(#Ikx9`JZoQFz0n*7ZG@Fv@kZk`gzO$HoA9kN z8U5{-yY zvV{`&WKU2$mZeoBmiJrEdzUZAv1sRxpePdg1)F*X^Y)zp^Y*R;;z~vOv-z&)&G)JQ{m!C9cmziu1^nHA z`#`0c>@PnQ9CJKgC5NjJD8HM3|KC(g5nnCq$n0Gsu_DXk36@ql%npEye|?%RmG)

FJ$wK}0tWNB{uH;AM~i diff --git a/example/app-test/android/src/main/res/mipmap-xhdpi/ic_launcher.webp b/example/app-test/android/src/main/res/mipmap-xhdpi/ic_launcher.webp deleted file mode 100644 index 948a3070fe34c611c42c0d3ad3013a0dce358be0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1900 zcmV-y2b1_xNk&Fw2LJ$9MM6+kP&il$0000G0001A003VA06|PpNH75a00DqwTbm-~ zullQTcXxO9ki!OCRx^i?oR|n!<8G0=kI^!JSjFi-LL*`V;ET0H2IXfU0*i>o6o6Gy zRq6Ap5(_{XLdXcL-MzlN`ugSdZY_`jXhcENAu)N_0?GhF))9R;E`!bo9p?g?SRgw_ zEXHhFG$0{qYOqhdX<(wE4N@es3VIo$%il%6xP9gjiBri+2pI6aY4 zJbgh-Ud|V%3O!IcHKQx1FQH(_*TK;1>FQWbt^$K1zNn^cczkBs=QHCYZ8b&l!UV{K z{L0$KCf_&KR^}&2Fe|L&?1I7~pBENnCtCuH3sjcx6$c zwqkNkru);ie``q+_QI;IYLD9OV0ZxkuyBz|5<$1BH|vtey$> z5oto4=l-R-Aaq`Dk0}o9N0VrkqW_#;!u{!bJLDq%0092{Ghe=F;(kn} z+sQ@1=UlX30+2nWjkL$B^b!H2^QYO@iFc0{(-~yXj2TWz?VG{v`Jg zg}WyYnwGgn>{HFaG7E~pt=)sOO}*yd(UU-D(E&x{xKEl6OcU?pl)K%#U$dn1mDF19 zSw@l8G!GNFB3c3VVK0?uyqN&utT-D5%NM4g-3@Sii9tSXKtwce~uF zS&Jn746EW^wV~8zdQ1XC28~kXu8+Yo9p!<8h&(Q({J*4DBglPdpe4M_mD8AguZFn~ ztiuO~{6Bx?SfO~_ZV(GIboeR9~hAym{{fV|VM=77MxDrbW6`ujX z<3HF(>Zr;#*uCvC*bpoSr~C$h?_%nXps@A)=l_;({Fo#6Y1+Zv`!T5HB+)#^-Ud_; zBwftPN=d8Vx)*O1Mj+0oO=mZ+NVH*ptNDC-&zZ7Hwho6UQ#l-yNvc0Cm+2$$6YUk2D2t#vdZX-u3>-Be1u9gtTBiMB^xwWQ_rgvGpZ6(C@e23c!^K=>ai-Rqu zhqT`ZQof;9Bu!AD(i^PCbYV%yha9zuoKMp`U^z;3!+&d@Hud&_iy!O-$b9ZLcSRh? z)R|826w}TU!J#X6P%@Zh=La$I6zXa#h!B;{qfug}O%z@K{EZECu6zl)7CiNi%xti0 zB{OKfAj83~iJvmpTU|&q1^?^cIMn2RQ?jeSB95l}{DrEPTW{_gmU_pqTc)h@4T>~& zluq3)GM=xa(#^VU5}@FNqpc$?#SbVsX!~RH*5p0p@w z;~v{QMX0^bFT1!cXGM8K9FP+=9~-d~#TK#ZE{4umGT=;dfvWi?rYj;^l_Zxywze`W z^Cr{55U@*BalS}K%Czii_80e0#0#Zkhlij4-~I@}`-JFJ7$5{>LnoJSs??J8kWVl6|8A}RCGAu9^rAsfCE=2}tHwl93t0C?#+jMpvr7O3`2=tr{Hg$=HlnjVG^ewm|Js0J*kfPa6*GhtB>`fN!m#9J(sU!?(OSfzY*zS(FJ<-Vb zfAIg+`U)YaXv#sY(c--|X zEB+TVyZ%Ie4L$gi#Fc++`h6%vzsS$pjz9aLt+ZL(g;n$Dzy5=m=_TV(3H8^C{r0xd zp#a%}ht55dOq?yhwYPrtp-m1xXp;4X;)NhxxUpgP%XTLmO zcjaFva^}dP3$&sfFTIR_jC=2pHh9kpI@2(6V*GQo7Ws)`j)hd+tr@P~gR*2gO@+1? zG<`_tB+LJuF|SZ9tIec;h%}}6WClT`L>HSW?E{Hp1h^+mlbf_$9zA>!ug>NALJsO{ mU%z=YwVD?}XMya)Bp;vlyE5&E_6!fzx9pwrdz474!~g(M6R?N? diff --git a/example/app-test/android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/example/app-test/android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp deleted file mode 100644 index 1b9a6956b3acdc11f40ce2bb3f6efbd845cc243f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3918 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�(p-{x$&=IACIfoAR!za)F-^da-t3#0Dycnp zwO~NVXwXCl;jE<}>%@xz|=8fIJAB?>+E{7)|4l${4ngA3G|=r z2Dyv;VVWSgZx9Wj>qUjleGl3Ei9K4>h!(lPS%8VOG>Xu0%6VDz^O=bjJmuP7>DeUv zrbI}MlHB^^d?{zv6d=@_ZD2lg1&G7UjnVN{1}9WkaM3H~btX0GtSzB+tZ^qRgWo4m z!GmimlG$=wgXCnr6j@m<1gAL46#T~5Bnm=2{^@>|t&`9mkEPddj zAvG~@Tv~TAm2i%VW}R-g(Z0)z-Y|szHr@rk>4MAyG*Ma*7Yh#H7(!-5>DZ@8r;_dx z{prSe<>~099F8vsYd2xff7uAS%7{S)f(|@me3t2$iy&NEc7OUEchp@9A|X;;IA>8!oX+y(BKJ$EzV* znR$z;!L$s7uy@{OT~nG#B!NRraT8(X##Ho!0r_o@gg0CA-9H^;-uE&?$2$nHv_00o z%cbuUc-tCx$Uh&EZ4Nf4Zgqv)Y6>usG3>GeQnxx_Z6+PcbX-+ysbt1hQ`K1LDpOE? zrAhIZhSN9yVIAOa22gn577tbc&i3|3V8NWy&!tw##`}9*x}gtI^h1DzZRA>UuaJG) zaZ7j)dq!O}{?#8Y7~7i6fHh4{`pL?>-18|p!S75Y#^DM>-S3)vuZG+Q7l@ek zQP~#cBpWgg#mApc_sPYjpw8odQuRokmTkzcNl`^CcKB7e&;zViV;{Y{o^Y$%7i0m# z62%#1Lq!RC?}lK>%mp}T!3Xv;L*0v*>USLm``N%>w>@fwC+#T&Tx2bN4w(20JB}oU zuSa6v^kXi0xPs?pbaOHnyiqq6By1EZY9OZ^^QA>{q-Hsd&m`pbQ%8121aWG-F5xf zlZ%;B{;C>X19|`^_?dVyCq>n+41w7|!tUS!{9rHlbhX=SZO5CQ^;!Du_E7*`GiR^Q w)2!4MKjfSAeNo!9>IaV6aUZ*?W>} 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

UmY2RIYtNPVDpE$%vda+HD#3m z&VuXJ{BK&Qe+rBa7eq}Q(bq|tn(RrJAk|ztj2(i{d>nmQnM?;HF2k&9sA6up5tmjl z7lySlzMbifH17-m-Lwa_F&e7nOH?ESi3#ckR3tsM+jsck3`oG!uMS}|eAwVXv>}qxwq?QY%QJ0}r@^;fhuUA9W z*BVl>TGo&N004@xSiwDUXUvp51sVmqO3m)=B55aPwf@0=e}cN+$-BdKxY`YrT_4)0 z_d10#i44Q*rFr8MC>*)v$EJvz``(pb{e&*6k+b zsMz%($|1+8hn8c2?P(l@;Rb&CsZeYoCI3?2!LqjbwPXW3z4G$Qfj=cT5Yb%vY0(AX oeb?AaKtwrnc|$|zzw9vfvn^aJJ!zd)XFXqqy0000001=f@-~a#s diff --git a/example/app-test/android/src/main/res/values/colors.xml b/example/app-test/android/src/main/res/values/colors.xml deleted file mode 100644 index f8c6127d..00000000 --- a/example/app-test/android/src/main/res/values/colors.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - #FFBB86FC - #FF6200EE - #FF3700B3 - #FF03DAC5 - #FF018786 - #FF000000 - #FFFFFFFF - \ No newline at end of file diff --git a/example/app-test/android/src/main/res/values/strings.xml b/example/app-test/android/src/main/res/values/strings.xml deleted file mode 100644 index abe3d1df..00000000 --- a/example/app-test/android/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - TestLib - \ No newline at end of file diff --git a/example/app-test/core/build.gradle.kts b/example/app-test/core/build.gradle.kts deleted file mode 100644 index adeffa84..00000000 --- a/example/app-test/core/build.gradle.kts +++ /dev/null @@ -1,5 +0,0 @@ -dependencies { - implementation(project(":example:lib-test:lib-core")) - - implementation("com.badlogicgames.gdx:gdx:${LibExt.gdxVersion}") -} \ No newline at end of file diff --git a/example/app-test/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTestLib.java b/example/app-test/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTestLib.java deleted file mode 100644 index b74d0ccf..00000000 --- a/example/app-test/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTestLib.java +++ /dev/null @@ -1,375 +0,0 @@ -package com.github.xpenatan.jparser.example.app; - -import com.badlogic.gdx.ApplicationAdapter; -import com.badlogic.gdx.utils.ScreenUtils; -import lib.test.ArrayArgumentTest; -import lib.test.ArrayClass; -import lib.test.Child1; -import lib.test.Child2; -import lib.test.EnumClass; -import lib.test.EnumClass_EnumWithinClass; -import lib.test.Inner; -import lib.test.ObjectFactory; -import lib.test.Parent; -import lib.test.ReceiveArrays; -import lib.test.RefUser; -import lib.test.StoreArray; -import lib.test.StringUser; -import lib.test.StructInArray; -import lib.test.TestLibLoader; -import lib.test.TypeTestClass; -import lib.test.VoidPointerUser; -import lib.test.idl.helper.IDLByteArray; -import lib.test.idl.helper.IDLIntArray; -import static lib.test.AnEnum.enum_value1; -import static lib.test.AnEnum.enum_value2; -import static lib.test.EnumNamespace_EnumInNamespace.e_namespace_val; - -public class AppTestLib extends ApplicationAdapter { - private boolean init = false; - - @Override - public void create() { - TestLibLoader.init(new Runnable() { - @Override - public void run() { - init = true; - } - }); - } - - @Override - public void render() { - ScreenUtils.clear(0.4f, 0.4f, 0.4f, 1); - if(init) { - init = false; - initLib(); - } - } - - - private void initLib() { - test(); - } - - private void test() { - Console console = new Console(); - - // Part 1 - - var sme = new Parent(42); - sme.mulVal(2); - console.log("*"); - console.log(sme.getVal()); - console.log(sme.getAsConst()); - console.log(sme.voidStar(sme.getCPointer())); - console.log(sme.get_immutableAttr()); - console.log(sme.get_immutableAttr()); - - console.log(sme.get_attr()); - sme.set_attr(9); - console.log(sme.get_attr()); - sme.set_attr(10); - console.log(sme.get_attr()); - - console.log(sme.getBoolean()); - - console.log("c1"); -// - var c1 = new Child1(); - console.log(c1.getVal()); - c1.mulVal(2); - console.log(c1.getVal()); - console.log(c1.getValSqr()); - console.log(c1.getValSqr(3)); -// console.log(c1.getValTimes()); // default argument should be 1 -// console.log(c1.getValTimes(2)); - console.log(sme.getBoolean()); - c1.parentFunc(90); - - console.log("c1 v2"); -// - c1 = new Child1(8); // now with a parameter, we should handle the overloading automatically and properly and use constructor #2 - console.log(c1.getVal()); - c1.mulVal(2); - console.log(c1.getVal()); - console.log(c1.getValSqr()); - console.log(c1.getValSqr(3)); - console.log(sme.getBoolean()); - - console.log("c2"); - - int succeeded = 0; - - var c2 = new Child2(); - console.log(c2.getVal()); - c2.mulVal(2); - console.log(c2.getVal()); - console.log(c2.getValCube()); - try { - succeeded = 0; - c2.getValCube(); // sanity - succeeded = 1; - } catch(Throwable t) {} - console.log(succeeded); - - Child2.printStatic(42); // static calls go through the prototype - - // virtual function -// c2.virtualFunc(); -// Child2.runVirtualFunc(c2); -// c2.virtualFunc2(); - - // extend a class from JS -// var c3 = new TheModule.Child2JS; -// -// c3.virtualFunc = function() { -// console.log('*js virtualf replacement*'); -// }; -// c3.virtualFunc2 = function() { -// console.log('*js virtualf2 replacement*'); -// }; -// c3.virtualFunc3 = function(x) { -// console.log('*js virtualf3 replacement ' + x + '*'); -// }; -// -// c3.virtualFunc(); -// TheModule.Child2.prototype.runVirtualFunc(c3); -// c3.virtualFunc2(); -// c3.virtualFunc3(123); // this one is not replaced! -// try { -// c3.virtualFunc4(123); -// } catch(e) { -// console.log('caught: ' + e); -// } -// - // Test virtual method dispatch from c++ -// Child2.runVirtualFunc3(c3, 43); -// -// c2.virtualFunc(); // original should remain the same -// Child2.runVirtualFunc(c2); -// c2.virtualFunc2(); -// console.log("*ok*"); - - // Part 2 - - var suser = new StringUser("hello", 43); - suser.Print(41, "world"); - suser.PrintFloat(12.3456f); -// console.log(suser.returnAString()); - - var bv = new RefUser(10); - var bv2 = new RefUser(11); - console.log(bv2.getValue(bv)); - - console.log(bv2.getMe().getClass()); - console.log(bv2.getMe().getValue(bv)); - console.log(bv2.getMe().getValue(bv2)); - - console.log(bv2.getCopy().getClass()); - console.log(bv2.getCopy().getValue(bv)); - console.log(bv2.getCopy().getValue(bv2)); - - bv2.getAnother().PrintFloat(21.12f); - - console.log(new Inner().get()); -// console.log('getAsArray: ' + new Inner().getAsArray(12)); -// new Inner().mul(2); -// new Inner().incInPlace(new Inner()); - - console.log(enum_value1); - console.log(enum_value2); - - // Enums from classes are accessed via the class. - var enumClassInstance = new EnumClass(); - console.log(enumClassInstance.GetEnum()); - console.log(EnumClass_EnumWithinClass.e_val); -// console.log([enumClassInstance.GetEnum(), EnumClass.e_val].join(',')); - - // Enums from namespaces are accessed via the top-level module, as with classes defined - // in namespaces, see `Inner` above. - console.log(e_namespace_val); - - var typeTester = new TypeTestClass(); - - console.log("return char " + (typeTester.ReturnCharMethod() & 255)); - typeTester.AcceptCharMethod((byte)((2<<6)-1)); - typeTester.AcceptCharMethod((byte)-1); - -// console.log("return unsigned char " + (typeTester.ReturnUnsignedCharMethod() & 255)); -// typeTester.AcceptUnsignedCharMethod((2<<7)-1); - - console.log("return unsigned short " + (typeTester.ReturnUnsignedShortMethod() & 65535)); - typeTester.AcceptUnsignedShortMethod((short)((2<<15)-1)); - - console.log("return unsigned long " + (typeTester.ReturnUnsignedLongMethod() | 0)); - typeTester.AcceptUnsignedLongMethod((2<<31)-1); - var voidPointerUser = new VoidPointerUser(); - - voidPointerUser.SetVoidPointer(3); - console.log("void * " + voidPointerUser.GetVoidPointer()); - - // Array tests - - var arrayClass = new ArrayClass(); -// console.log("int_array[0] == " + arrayClass.get_int_array(0)); -// console.log("int_array[7] == " + arrayClass.get_int_array(7)); -// arrayClass.set_int_array(0, 42); -// arrayClass.set_int_array(7, 43); -// console.log("int_array[0] == " + arrayClass.get_int_array(0)); -// console.log("int_array[7] == " + arrayClass.get_int_array(7)); - -// try { -// arrayClass.set_int_array(-1, 42); -// } catch (Throwable e) { -// console.log("idx -1: " + e); -// } - -// try { -// arrayClass.set_int_array(8, 42); -// } catch (Throwable e) { -// console.log("idx 8: " + e); -// } -// -// console.log("struct_array[0].attr1 == " + arrayClass.get_struct_array(0).get_attr1()); -// console.log("struct_array[0].attr2 == " + arrayClass.get_struct_array(0).get_attr2()); -// console.log("struct_array[7].attr1 == " + arrayClass.get_struct_array(7).get_attr1()); -// console.log("struct_array[7].attr2 == " + arrayClass.get_struct_array(7).get_attr2()); - - // Verify that bounds checking is *not* enabled when not asked for. - // This actually causes an illegal memory access, but as it's only a read, and the return - // value is not used, it shouldn't cause any problems in practice. -// arrayClass.get_struct_array(8); -// - var struct = new StructInArray(13, 17); -// arrayClass.set_struct_array(0, struct); - struct = new StructInArray(14, 18); -// arrayClass.set_struct_array(7, struct); - -// console.log("struct_array[0].attr1 == " + arrayClass.get_struct_array(0).get_attr1()); -// console.log("struct_array[0].attr2 == " + arrayClass.get_struct_array(0).get_attr2()); -// console.log("struct_array[7].attr1 == " + arrayClass.get_struct_array(7).get_attr1()); -// console.log("struct_array[7].attr2 == " + arrayClass.get_struct_array(7).get_attr2()); -// - struct = new StructInArray(100, 101); -// arrayClass.set_struct_ptr_array(0, struct); -// console.log("struct_ptr_array[0]->attr1 == " + arrayClass.get_struct_ptr_array(0).get_attr1()); -// console.log("struct_ptr_array[0]->attr2 == " + arrayClass.get_struct_ptr_array(0).get_attr2()); - - // receiving arrays - - var receiver = new ReceiveArrays(); -// receiver.giveMeArrays([0.5, 0.25, 0.01, -20.42], [1, 4, 9, 10], 4); - - // Test IDL_CHECKS=ALL - -// try { -// p = new Parent(NaN); // Expects an integer -// } catch (e) {} - - try { - Parent p = new Parent(42); - p.voidStar(1234); // Expects a wrapped pointer - } catch (Throwable e) {} - - try { - StringUser s = new StringUser("abc", 1); - s.Print(123, null); // Expects a string or a wrapped pointer - } catch (Throwable e) {} - - // Returned pointers (issue 14745) - - var factory = new ObjectFactory(); - var objectProvider = factory.getProvider(); - var smallObject = objectProvider.getObject(); - - // This will print 123 if we managed to access the object, which means that integers - // were correctly typecast to ObjectProvider pointer and SmallObject pointer. - console.log(smallObject.getID(123)); - - factory.dispose(); - - // end of issue 14745 - - // octet[] to char* (issue 14827) - - var arrayTestObj = new ArrayArgumentTest(); - var bufferAddr = new IDLByteArray(35); -// TheModule.stringToUTF8('I should match the member variable', bufferAddr, 35); - - var arrayTestResult = arrayTestObj.byteArrayTest(bufferAddr); - var arrayDomStringResult = arrayTestObj.domStringTest("I should match the member variable"); - console.log(arrayTestResult); - console.log(arrayDomStringResult); - - arrayTestObj.dispose(); - - bufferAddr.dispose(); - // end of issue 14827 - - // Check for overflowing the stack - -// var before = Date.now(); -// -// for (var i = 0; i < 1000000; i++) { -// var temp = new TheModule.StringUser('abc', 1); -// TheModule.destroy(temp); -// if (Date.now() - before >= 1000) break; -// } - - boolean isMemoryGrowthAllowed = true; - if(isMemoryGrowthAllowed) { - // Check for HEAP reallocation when using large arrays - var numArrayEntries = 100000; - var intArray = new IDLIntArray(numArrayEntries); - for (var i = 0; i < numArrayEntries; i++) { - intArray.setValue(i, i); - } - -// var startHeapLength = TheModule['HEAP8'].length; - int offset; - var storeArray = new StoreArray(); - storeArray.setArray(intArray); - // Add more data until the heap is reallocated -// while (TheModule['HEAP8'].length === startHeapLength) { -// intArray = intArray.concat(intArray); -// storeArray.setArray(intArray); -// } -// -// // Make sure the array was copied to the newly allocated HEAP -// var numCopiedEntries = 0; -// for (var i = 0; i < intArray.length; i++) { -// if (storeArray.getArrayValue(i) !== intArray[i]) { -// break; -// } -// numCopiedEntries += 1; -// } -// -// if (intArray.length !== numCopiedEntries) { -// console.log('ERROR: An array was not copied to HEAP32 after memory reallocation'); -// } - } - console.log("\ndone."); - } - - static class Console { - public void log(Object text) { - System.out.println(text); - } - public void log(Class text) { - System.out.println(text); - } - public void log(int text) { - System.out.println(text); - } - public void log(float text) { - System.out.println(text); - } - public void log(boolean text) { - System.out.println(text); - } - public void log(String text) { - System.out.println(text); - } - } -} \ No newline at end of file diff --git a/example/app-test/desktop/assets/data/badlogic.jpg b/example/app-test/desktop/assets/data/badlogic.jpg deleted file mode 100644 index 4390da6e0f6d041590c6313d2b4c978abc00a342..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68465 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%0D_mtl(=kJ_v@+V;1Dd59><)1Vxf({Tq^pY-s)84 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 diff --git a/example/app-test/desktop/build.gradle.kts b/example/app-test/desktop/build.gradle.kts deleted file mode 100644 index d9a014c6..00000000 --- a/example/app-test/desktop/build.gradle.kts +++ /dev/null @@ -1,22 +0,0 @@ -import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform - -dependencies { - implementation(project(":example:app-test:core")) - implementation(project(":example:lib-test:lib-desktop")) - - implementation("com.badlogicgames.gdx:gdx-platform:${LibExt.gdxVersion}:natives-desktop") - implementation("com.badlogicgames.gdx:gdx-backend-lwjgl3:${LibExt.gdxVersion}") -} - -val mainClassName = "com.github.xpenatan.jparser.example.app.Main" - -tasks.register("run-app-desktop") { - group = "example-desktop" - description = "Run desktop app" - mainClass.set(mainClassName) - classpath = sourceSets["main"].runtimeClasspath - - if(DefaultNativePlatform.getCurrentOperatingSystem().isMacOsX) { - jvmArgs("-XstartOnFirstThread") - } -} \ No newline at end of file diff --git a/example/app-test/desktop/src/main/java/com/github/xpenatan/jparser/example/app/Main.java b/example/app-test/desktop/src/main/java/com/github/xpenatan/jparser/example/app/Main.java deleted file mode 100644 index 55da9100..00000000 --- a/example/app-test/desktop/src/main/java/com/github/xpenatan/jparser/example/app/Main.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.xpenatan.jparser.example.app; - -import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application; -import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration; - -public class Main { - - public static void main(String[] args) { - Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration(); - new Lwjgl3Application(new AppTestLib(), config); - } -} \ No newline at end of file diff --git a/example/app-test/teavm/build.gradle.kts b/example/app-test/teavm/build.gradle.kts deleted file mode 100644 index 53adc2bc..00000000 --- a/example/app-test/teavm/build.gradle.kts +++ /dev/null @@ -1,34 +0,0 @@ -plugins { - id("org.gretty") version("3.1.0") -} - -gretty { - contextPath = "/" - extraResourceBase("build/dist/webapp") -} - -dependencies { - implementation(project(":example:app-test:core")) - implementation(project(":example:lib-test:lib-teavm")) - - implementation("com.badlogicgames.gdx:gdx:${LibExt.gdxVersion}") - implementation("com.github.xpenatan.gdx-teavm:backend-teavm:${LibExt.gdxTeaVMVersion}") -} - -val mainClassName = "Build" - -tasks.register("build-app-teavm") { - group = "example-teavm" - description = "Build teavm app" - mainClass.set(mainClassName) - classpath = sourceSets["main"].runtimeClasspath -} - -tasks.register("run-app-teavm") { - group = "example-teavm" - description = "Run teavm app" - val list = listOf("build-app-teavm", "jettyRun") - dependsOn(list) - - tasks.findByName("jettyRun")?.mustRunAfter("build-app-teavm") -} \ No newline at end of file diff --git a/example/app-test/teavm/src/main/java/Build.java b/example/app-test/teavm/src/main/java/Build.java deleted file mode 100644 index 3a9351bd..00000000 --- a/example/app-test/teavm/src/main/java/Build.java +++ /dev/null @@ -1,21 +0,0 @@ -import com.github.xpenatan.gdx.backends.teavm.config.AssetFileHandle; -import com.github.xpenatan.gdx.backends.teavm.config.TeaBuildConfiguration; -import com.github.xpenatan.gdx.backends.teavm.config.TeaBuilder; -import com.github.xpenatan.gdx.backends.teavm.gen.SkipClass; -import java.io.File; -import java.io.IOException; -import org.teavm.tooling.TeaVMTool; - -@SkipClass -public class Build { - - public static void main(String[] args) throws IOException { - TeaBuildConfiguration teaBuildConfiguration = new TeaBuildConfiguration(); - teaBuildConfiguration.assetsPath.add(new AssetFileHandle("../desktop/assets")); - teaBuildConfiguration.webappPath = new File("build/dist").getCanonicalPath(); - TeaVMTool tool = TeaBuilder.config(teaBuildConfiguration); - tool.setMainClass(TeaVMLauncher.class.getName()); - tool.setObfuscated(false); - TeaBuilder.build(tool); - } -} diff --git a/example/app-test/teavm/src/main/java/TeaVMLauncher.java b/example/app-test/teavm/src/main/java/TeaVMLauncher.java deleted file mode 100644 index 1317b728..00000000 --- a/example/app-test/teavm/src/main/java/TeaVMLauncher.java +++ /dev/null @@ -1,13 +0,0 @@ -import com.github.xpenatan.gdx.backends.teavm.TeaApplication; -import com.github.xpenatan.gdx.backends.teavm.TeaApplicationConfiguration; -import com.github.xpenatan.jparser.example.app.AppTestLib; - -public class TeaVMLauncher { - public static void main(String[] args) { - TeaApplicationConfiguration config = new TeaApplicationConfiguration("canvas"); - config.width = 0; - config.height = 0; - config.showDownloadLogs = true; - new TeaApplication(new AppTestLib(), config); - } -} \ No newline at end of file diff --git a/example/lib-ext/ext-base/build.gradle.kts b/example/lib-ext/ext-base/build.gradle.kts deleted file mode 100644 index 32e15f30..00000000 --- a/example/lib-ext/ext-base/build.gradle.kts +++ /dev/null @@ -1,3 +0,0 @@ -dependencies { - implementation(project(":example:lib:lib-core")) -} \ No newline at end of file diff --git a/example/lib-ext/ext-base/src/main/java/com.lib.ext/CustomLib.java b/example/lib-ext/ext-base/src/main/java/com.lib.ext/CustomLib.java deleted file mode 100644 index a5ae433e..00000000 --- a/example/lib-ext/ext-base/src/main/java/com.lib.ext/CustomLib.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.lib.ext; - -public class CustomLib { - /*[-JNI;-NATIVE] - #include "CustomLib.h" - */ -} \ No newline at end of file diff --git a/example/lib-ext/ext-build/build.gradle.kts b/example/lib-ext/ext-build/build.gradle.kts deleted file mode 100644 index 489a61a4..00000000 --- a/example/lib-ext/ext-build/build.gradle.kts +++ /dev/null @@ -1,12 +0,0 @@ -plugins { - id("java") -} - -dependencies { - implementation(project(":example:lib:lib-core")) - implementation(project(":jParser:core")) - implementation(project(":jParser:idl")) - implementation(project(":jParser:teavm")) - implementation(project(":jParser:cpp")) - implementation(project(":jParser:builder")) -} \ No newline at end of file diff --git a/example/lib-ext/ext-build/src/main/cpp/ExtLib.idl b/example/lib-ext/ext-build/src/main/cpp/ExtLib.idl deleted file mode 100644 index 1f5e2cc1..00000000 --- a/example/lib-ext/ext-build/src/main/cpp/ExtLib.idl +++ /dev/null @@ -1,3 +0,0 @@ -interface CustomLib { - static void print(); -}; \ No newline at end of file diff --git a/example/lib-ext/ext-build/src/main/cpp/cpp-source/custom/CustomLib.cpp b/example/lib-ext/ext-build/src/main/cpp/cpp-source/custom/CustomLib.cpp deleted file mode 100644 index 90238a3c..00000000 --- a/example/lib-ext/ext-build/src/main/cpp/cpp-source/custom/CustomLib.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "CustomLib.h" \ No newline at end of file diff --git a/example/lib-ext/ext-build/src/main/cpp/cpp-source/custom/CustomLib.h b/example/lib-ext/ext-build/src/main/cpp/cpp-source/custom/CustomLib.h deleted file mode 100644 index 139ef638..00000000 --- a/example/lib-ext/ext-build/src/main/cpp/cpp-source/custom/CustomLib.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -class CustomLib { - -private: - -public: - - static void print() { - std::cout << " PRINT " << std::endl; - } -}; \ No newline at end of file diff --git a/example/lib-ext/ext-build/src/main/java/BuildExtCode.java b/example/lib-ext/ext-build/src/main/java/BuildExtCode.java deleted file mode 100644 index 595cd54b..00000000 --- a/example/lib-ext/ext-build/src/main/java/BuildExtCode.java +++ /dev/null @@ -1,71 +0,0 @@ -import com.github.xpenatan.jparser.builder.BuildConfig; -import com.github.xpenatan.jparser.builder.BuildMultiTarget; -import com.github.xpenatan.jparser.builder.BuildTarget; -import com.github.xpenatan.jparser.builder.JBuilder; -import com.github.xpenatan.jparser.builder.targets.WindowsTarget; -import com.github.xpenatan.jparser.core.JParser; -import com.github.xpenatan.jparser.core.util.FileHelper; -import com.github.xpenatan.jparser.cpp.CppCodeParser; -import com.github.xpenatan.jparser.cpp.CppGenerator; -import com.github.xpenatan.jparser.cpp.NativeCPPGenerator; -import com.github.xpenatan.jparser.idl.IDLReader; -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; - -public class BuildExtCode { - - public static void build() throws Exception { - String libName = "extlib"; - String basePackage = "com.lib.ext"; - - JParser.CREATE_IDL_HELPER = false; - - String libPath = new File("../../lib").getCanonicalPath().replace("\\", "/"); - String idlPath = new File("src/main/cpp/ExtLib.idl").getCanonicalPath(); - IDLReader idlReader = IDLReader.readIDL(idlPath); - String baseJavaDir = new File(".").getAbsolutePath() + "./ext-base/src/main/java"; - - String cppSourceDir = new File("./src/main/cpp/cpp-source//source/").getCanonicalPath(); - String libsDir = new File("./build/c++/libs/").getCanonicalPath(); - String libBuildPath = new File("./build/c++/").getCanonicalPath(); - String cppDestinationPath = libBuildPath + "/src"; - String libDestinationPath = cppDestinationPath + "/extlib"; - - FileHelper.copyDir(cppSourceDir, libDestinationPath); - - Path copyOut = new File(libDestinationPath).toPath(); - FileHelper.copyDir(new File("src/main/cpp/cpp-source/custom").toPath(), copyOut); - - CppGenerator cppGenerator = new NativeCPPGenerator(libDestinationPath); - CppCodeParser cppParser = new CppCodeParser(cppGenerator, idlReader, basePackage, cppSourceDir); - cppParser.generateClass = true; - JParser.generate(cppParser, baseJavaDir, "../ext-core/src/main/java"); - - BuildConfig buildConfig = new BuildConfig(cppDestinationPath, libBuildPath, libsDir, libName); - - ArrayList targets = new ArrayList<>(); - if(BuildTarget.isWindows() || BuildTarget.isUnix()) { -// targets.add(getWindowBuildTarget(libPath)); - } - - JBuilder.build(buildConfig, targets); - } - - private static BuildMultiTarget getWindowBuildTarget(String libPath) throws IOException { - BuildMultiTarget multiTarget = new BuildMultiTarget(); - - String libCppPath = libPath + "/generator/build/c++"; - - WindowsTarget windowsTarget = new WindowsTarget(); - windowsTarget.headerDirs.add("-I" + libCppPath + "/src/imgui"); - windowsTarget.isStatic = true; - windowsTarget.headerDirs.add("-Isrc/extlib/"); - windowsTarget.cppInclude.add("**/extlib/*.cpp"); - multiTarget.add(windowsTarget); - - return multiTarget; - } - -} \ No newline at end of file diff --git a/example/lib-ext/ext-core/build.gradle.kts b/example/lib-ext/ext-core/build.gradle.kts deleted file mode 100644 index 65c3f593..00000000 --- a/example/lib-ext/ext-core/build.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -plugins { - id("java") -} - -dependencies { - implementation(project(":example:lib:lib-core")) -} - -tasks.named("clean") { - doFirst { - val srcPath = "$projectDir/src/main/" - project.delete(files(srcPath)) - } -} \ No newline at end of file diff --git a/example/lib-ext/ext-teavm/build.gradle.kts b/example/lib-ext/ext-teavm/build.gradle.kts deleted file mode 100644 index 0a542292..00000000 --- a/example/lib-ext/ext-teavm/build.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ -plugins { - id("java") -} - - -dependencies { - implementation(project(":example:lib:lib-core")) - implementation("org.teavm:teavm-jso:${LibExt.teaVMVersion}") - implementation("org.teavm:teavm-classlib:${LibExt.teaVMVersion}") -} - -tasks.named("clean") { - doFirst { - val srcPath = "$projectDir/src/main/java/gen" - project.delete(files(srcPath)) - } -} \ No newline at end of file diff --git a/example/lib-ext/ext-teavm/src/main/resources/META-INF/gdx-teavm.properties b/example/lib-ext/ext-teavm/src/main/resources/META-INF/gdx-teavm.properties deleted file mode 100644 index e69de29b..00000000 diff --git a/example/lib-ext/ext-teavm/src/main/resources/META-INF/teavm.properties b/example/lib-ext/ext-teavm/src/main/resources/META-INF/teavm.properties deleted file mode 100644 index b5be5cb7..00000000 --- a/example/lib-ext/ext-teavm/src/main/resources/META-INF/teavm.properties +++ /dev/null @@ -1 +0,0 @@ -mapPackageHierarchy|gen.com=com \ No newline at end of file diff --git a/example/lib-test/lib-android/build.gradle.kts b/example/lib-test/lib-android/build.gradle.kts deleted file mode 100644 index fb8feb26..00000000 --- a/example/lib-test/lib-android/build.gradle.kts +++ /dev/null @@ -1,31 +0,0 @@ -plugins { - id("com.android.library") - kotlin("android") -} - -group = "lib.escripte" - -android { - namespace = "lib.escripten" - compileSdk = 33 - - defaultConfig { - minSdk = 21 - } - - sourceSets { - named("main") { - jniLibs.srcDirs("$projectDir/../lib-build/build/c++/libs/android") - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - kotlinOptions { - jvmTarget = "11" - } -} - -dependencies { -} \ No newline at end of file diff --git a/example/lib-test/lib-base/build.gradle.kts b/example/lib-test/lib-base/build.gradle.kts deleted file mode 100644 index 27df264c..00000000 --- a/example/lib-test/lib-base/build.gradle.kts +++ /dev/null @@ -1,10 +0,0 @@ -dependencies { - if(LibExt.exampleUseRepoLibs) { - implementation("com.github.xpenatan.jParser:base:${LibExt.libVersion}") - implementation("com.github.xpenatan.jParser:loader-core:${LibExt.libVersion}") - } - else { - implementation(project(":jParser:base")) - implementation(project(":jParser:loader:loader-core")) - } -} \ No newline at end of file diff --git a/example/lib-test/lib-base/src/main/java/lib/test/TestLibLoader.java b/example/lib-test/lib-base/src/main/java/lib/test/TestLibLoader.java deleted file mode 100644 index 6ddda5dd..00000000 --- a/example/lib-test/lib-base/src/main/java/lib/test/TestLibLoader.java +++ /dev/null @@ -1,42 +0,0 @@ -package lib.test; - -import com.github.xpenatan.jparser.loader.JParserLibraryLoader; - -public class TestLibLoader { - - /*[-JNI;-NATIVE] - #include "CustomCode.h" - */ - - /*[-TEAVM;-ADD] - @org.teavm.jso.JSFunctor - public interface OnInitFunction extends org.teavm.jso.JSObject { - void onInit(); - } - */ - - /*[-TEAVM;-REPLACE] - public static void init(Runnable onSuccess) { - JParserLibraryLoader libraryLoader = new JParserLibraryLoader(); - OnInitFunction onInitFunction = () -> onSuccess.run(); - setOnLoadInit(onInitFunction); - libraryLoader.load("test.wasm", isSuccess -> {}); - } - */ - - public static void init(Runnable onSuccess) { - JParserLibraryLoader libraryLoader = new JParserLibraryLoader(); - libraryLoader.load("test", isSuccess -> { - if(isSuccess) { - onSuccess.run(); - } - }); - } - - /*[-TEAVM;-REPLACE] - @org.teavm.jso.JSBody(params = { "onInitFunction" }, script = "window.exampleLibOnInit = onInitFunction;") - private static native void setOnLoadInit(OnInitFunction onInitFunction); - */ - /*[-JNI;-REMOVE] */ - public static native void setOnLoadInit(); -} \ No newline at end of file diff --git a/example/lib-test/lib-build/build.gradle.kts b/example/lib-test/lib-build/build.gradle.kts deleted file mode 100644 index fb4904a2..00000000 --- a/example/lib-test/lib-build/build.gradle.kts +++ /dev/null @@ -1,98 +0,0 @@ -plugins { - id("java") -} - -val mainClassName = "BuildLib" - -dependencies { - implementation(project(":example:lib-test:lib-base")) - - if(LibExt.exampleUseRepoLibs) { - implementation("com.github.xpenatan.jParser:core:${LibExt.libVersion}") - implementation("com.github.xpenatan.jParser:idl:${LibExt.libVersion}") - implementation("com.github.xpenatan.jParser:teavm:${LibExt.libVersion}") - implementation("com.github.xpenatan.jParser:cpp:${LibExt.libVersion}") - implementation("com.github.xpenatan.jParser:builder:${LibExt.libVersion}") - implementation("com.github.xpenatan.jParser:builder-tool:${LibExt.libVersion}") - } - else { - implementation(project(":jParser:core")) - implementation(project(":jParser:idl")) - implementation(project(":jParser:teavm")) - implementation(project(":jParser:cpp")) - implementation(project(":jParser:builder")) - implementation(project(":jParser:builder-tool")) - } -} - -tasks.register("build_project") { - group = "lib" - description = "Generate native project" - mainClass.set(mainClassName) - args = mutableListOf() - classpath = sourceSets["main"].runtimeClasspath -} - -tasks.register("build_project_all") { - group = "lib" - description = "Generate native project" - mainClass.set(mainClassName) - args = mutableListOf("teavm", "windows64", "linux64", "mac64", "macArm", "android", "ios") - classpath = sourceSets["main"].runtimeClasspath -} - -tasks.register("build_project_teavm") { - group = "lib" - description = "Generate native project" - mainClass.set(mainClassName) - args = mutableListOf("teavm") - classpath = sourceSets["main"].runtimeClasspath -} - -tasks.register("build_project_windows64") { - group = "lib" - description = "Generate native project" - mainClass.set(mainClassName) - args = mutableListOf("windows64") - classpath = sourceSets["main"].runtimeClasspath -} - -tasks.register("build_project_linux64") { - group = "lib" - description = "Generate native project" - mainClass.set(mainClassName) - args = mutableListOf("linux64") - classpath = sourceSets["main"].runtimeClasspath -} - -tasks.register("build_project_mac64") { - group = "lib" - description = "Generate native project" - mainClass.set(mainClassName) - args = mutableListOf("mac64") - classpath = sourceSets["main"].runtimeClasspath -} - -tasks.register("build_project_macArm") { - group = "lib" - description = "Generate native project" - mainClass.set(mainClassName) - args = mutableListOf("macArm") - classpath = sourceSets["main"].runtimeClasspath -} - -tasks.register("build_project_android") { - group = "lib" - description = "Generate native project" - mainClass.set(mainClassName) - args = mutableListOf("android") - classpath = sourceSets["main"].runtimeClasspath -} - -tasks.register("build_project_ios") { - group = "lib" - description = "Generate native project" - mainClass.set(mainClassName) - args = mutableListOf("ios") - classpath = sourceSets["main"].runtimeClasspath -} \ No newline at end of file diff --git a/example/lib-test/lib-build/src/main/cpp/custom/CustomCode.cpp b/example/lib-test/lib-build/src/main/cpp/custom/CustomCode.cpp deleted file mode 100644 index 9df9a23a..00000000 --- a/example/lib-test/lib-build/src/main/cpp/custom/CustomCode.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "CustomCode.h" \ No newline at end of file diff --git a/example/lib-test/lib-build/src/main/cpp/custom/CustomCode.h b/example/lib-test/lib-build/src/main/cpp/custom/CustomCode.h deleted file mode 100644 index 001b9b6c..00000000 --- a/example/lib-test/lib-build/src/main/cpp/custom/CustomCode.h +++ /dev/null @@ -1,4 +0,0 @@ -#include "test.h" - -typedef EnumClass::EnumWithinClass EnumClass_EnumWithinClass; -typedef EnumNamespace::EnumInNamespace EnumNamespace_EnumInNamespace; \ No newline at end of file diff --git a/example/lib-test/lib-build/src/main/cpp/source/testLib/src/test.cpp b/example/lib-test/lib-build/src/main/cpp/source/testLib/src/test.cpp deleted file mode 100644 index 9fb03a03..00000000 --- a/example/lib-test/lib-build/src/main/cpp/source/testLib/src/test.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// THIS FILE WAS DOWNLOADED FROM EMSCRIPTEN WEBIDL TEST (09/AUG/2024) - -#include "test.h" - -Parent::Parent(int val) : value(val), attr(6), immutableAttr(8) { - printf("Parent:%d\n", val); -} - -Parent::Parent(Parent* p, Parent* q) - : value(p->value + q->value), attr(6), immutableAttr(8) { - printf("Parent:%d\n", value); -} - -void Parent::mulVal(int mul) { value *= mul; } - diff --git a/example/lib-test/lib-build/src/main/cpp/source/testLib/src/test.h b/example/lib-test/lib-build/src/main/cpp/source/testLib/src/test.h deleted file mode 100644 index b1b646ed..00000000 --- a/example/lib-test/lib-build/src/main/cpp/source/testLib/src/test.h +++ /dev/null @@ -1,243 +0,0 @@ -// THIS FILE WAS DOWNLOADED FROM EMSCRIPTEN WEBIDL TEST (09/AUG/2024) - -#include -#include - -// Part 1 - -class Parent { -protected: - int value; -public: - Parent(int val); - Parent(Parent *p, Parent *q); // overload constructor - int getVal() { return value; }; // inline should work just fine here, unlike Way 1 before - void mulVal(int mul); - void parentFunc() {} - const Parent *getAsConst() { return NULL; } - void *voidStar(void *something) { return something; } - bool getBoolean() { return true; } - int attr; - const int immutableAttr; -}; - -class Child1 : public Parent { -public: - Child1() : Parent(7) { printf("Child1:%d\n", value); }; - Child1(int val) : Parent(val*2) { value -= 1; printf("Child1:%d\n", value); }; - int getValSqr() { return value*value; } - int getValSqr(int more) { return value*value*more; } - int getValTimes(int times=1) { return value*times; } - void parentFunc(int x) { printf("Child1::parentFunc(%d)\n", x); } -}; - -// Child2 has vtable, parent does not. Checks we cast child->parent properly - (Parent*)child is not a no-op, must offset -class Child2 : public Parent { -public: - Child2() : Parent(9) { printf("Child2:%d\n", value); }; - virtual ~Child2() = default; - int getValCube() { return value*value*value; } - static void printStatic(int arg0) { printf("*static*: %d\n", arg0); } - - virtual void virtualFunc() { printf("*virtualf*\n"); } - virtual void virtualFunc2() { printf("*virtualf2*\n"); } - static void runVirtualFunc(Child2 *self) { self->virtualFunc(); }; - virtual void virtualFunc3(int x) { printf("*virtualf3: %d*\n", x); } - virtual void virtualFunc4(int x) { printf("*virtualf4: %d*\n", x); } - static void runVirtualFunc3(Child2 *self, int x) { self->virtualFunc3(x); } - -private: - void doSomethingSecret() { printf("security breached!\n"); }; // we should not be able to do this -}; - -// We test compilation here: abstract base classes must be handled properly, -// and in particular the const property may matter (if not overridden as -// const, compilation will fail). -class VirtualBase { -public: - virtual ~VirtualBase() {}; - - virtual void func() = 0; - virtual void constFunc() const = 0; -}; - -// Part 2 - -#include - -class StringUser { - char *s; - int i; -public: - StringUser(const char *string="NO", int integer=99) : s(strdup(string)), i(integer) {} - ~StringUser() { free(s); } - void Print(int anotherInteger, char *anotherString) { - printf("|%s|%d|%s|%d|\n", s, i, anotherString, anotherInteger); - } - void PrintFloat(float f) { printf("%.2f\n", f); } - const char* returnAString() { return "a returned string"; } -}; - -struct RefUser { - int value; - RefUser(int x = 77) : value(x) {} - int getValue(RefUser b) { return b.value; } - RefUser &getMe() { return *this; } - RefUser getCopy() { return RefUser(value*2); } - StringUser getAnother() { return StringUser("another", 5); } -}; - -struct VoidPointerUser { - void *ptr; - - void *GetVoidPointer() { return ptr; } - void SetVoidPointer(void *p) { ptr = p; } -}; - -namespace Space { - struct Inner { - int value; - Inner() : value(1) {} - int get() { return 198; } - Inner& operator*=(float x) { return *this; } - int operator[](int x) { return x*2; } - void operator+=(const Inner& other) { - value += other.value; - printf("Inner::+= => %d\n", value); - } - }; - - // We test compilation of abstract base classes in a namespace here. - class InnerUserBase { - public: - virtual ~InnerUserBase() {}; - - virtual void Callback(Inner *inner) = 0; - }; -} - -enum AnEnum { - enum_value1, - enum_value2 -}; - -namespace EnumNamespace { - enum EnumInNamespace { - e_namespace_val = 78 - }; -}; - -class EnumClass { -public: - enum EnumWithinClass { - e_val = 34 - }; - EnumWithinClass GetEnum() { return e_val; } - - EnumNamespace::EnumInNamespace GetEnumFromNameSpace() { return EnumNamespace::e_namespace_val; } -}; - -class TypeTestClass { -public: - char ReturnCharMethod() { return (2<<6)-1; } - void AcceptCharMethod(char x) { printf("char: %d\n", x); } - - unsigned char ReturnUnsignedCharMethod() { return (2<<7)-1; } - void AcceptUnsignedCharMethod(unsigned char x) { printf("unsigned char: %u\n", x); } - - unsigned short int ReturnUnsignedShortMethod() { return (2<<15)-1; } - void AcceptUnsignedShortMethod(unsigned short x) { printf("unsigned short int: %u\n", x); } - - unsigned long ReturnUnsignedLongMethod() { return 0xffffffff; } - void AcceptUnsignedLongMethod(unsigned long x) { printf("unsigned long int: %lu\n", x); } -}; - -struct StructInArray { - StructInArray() : attr1(0), attr2(0) {} - StructInArray(int _attr1, int _attr2) : attr1(_attr1), attr2(_attr2) {} - int attr1; - int attr2; -}; - -class ArrayClass { -public: - ArrayClass() { - for (int i = 0; i < 8; i++) { - int_array[i] = i; - struct_array[i] = StructInArray(i, -i); - struct_ptr_array[i] = NULL; - } - } - int int_array[8]; - StructInArray struct_array[8]; - StructInArray* struct_ptr_array[8]; -}; - -struct ReceiveArrays { - void giveMeArrays(float* vertices, int* triangles, int num) { - for (int i = 0; i < num; i++) { - printf("%d : %.2f\n", triangles[i], vertices[i]); - } - } -}; - -struct StoreArray { - StoreArray() : int_array(NULL) {} - void setArray(const int *array) { - int_array = array; - } - int getArrayValue(int index) const { - return int_array[index]; - } - const int* int_array; -}; - -typedef struct LongLongTypes { - unsigned long long* lluArray; - long long ll; -} LongLongTypes; - -// Returning child objects in a hierarchy - -struct ISmallObject { - virtual int getID(int number) = 0; -}; - -struct IObjectProvider { - virtual ISmallObject* getObject() = 0; -}; - -class SmallObject : public ISmallObject { -public: - int getID(int number) { - return number; - } -}; - -class ObjectProvider : public IObjectProvider { -public: - ISmallObject* getObject() { - return &m_smallObject; - } -private: - SmallObject m_smallObject; -}; - -class ObjectFactory { -public: - IObjectProvider* getProvider() { - return &m_ObjectProvider; - } -private: - ObjectProvider m_ObjectProvider; -}; - -class ArrayArgumentTest { -public: - ArrayArgumentTest() : m_array("I should match the member variable"){}; - ~ArrayArgumentTest(){}; - bool byteArrayTest(const char* arg) { return strcmp(arg, m_array) == 0; } - bool domStringTest(const char* arg) { return strcmp(arg, m_array) == 0; } -private: - const char* m_array; -}; \ No newline at end of file diff --git a/example/lib-test/lib-build/src/main/cpp/test.idl b/example/lib-test/lib-build/src/main/cpp/test.idl deleted file mode 100644 index 32230ff5..00000000 --- a/example/lib-test/lib-build/src/main/cpp/test.idl +++ /dev/null @@ -1,212 +0,0 @@ -// THIS FILE WAS DOWNLOADED FROM EMSCRIPTEN WEBIDL TEST (09/AUG/2024) - -// Part 1 - -interface Parent { - void Parent(long val); - long getVal(); - void mulVal(long mul); - void parentFunc(); - [Const] Parent getAsConst(); - VoidPtr voidStar(VoidPtr something); - boolean getBoolean(); - attribute long attr; - readonly attribute long immutableAttr; -}; - -interface Child1 { - void Child1(optional long val); - long getValSqr(optional long more); -// long getValTimes(optional long times=1); - void parentFunc(long x); // redefinition, name collides with parent -}; - -Child1 implements Parent; - -interface Child2 { - void Child2(); - long getValCube(); - static void printStatic(long arg0); - void virtualFunc(); - void virtualFunc2(); - void virtualFunc3(long x); - void virtualFunc4(long x); - static void runVirtualFunc(Child2 myself); - static void runVirtualFunc3(Child2 myself, long x); -}; - -Child2 implements Parent; - -[JSImplementation="Child2"] -interface Child2JS { - void Child2JS(); - void virtualFunc(); - void virtualFunc2(); - void virtualFunc3(long x); - void virtualFunc4(long x); -}; - -interface VirtualBase { - void func(); - void constFunc(); -}; - -[JSImplementation="VirtualBase"] -interface ConcreteJS { - void ConcreteJS(); - void func(); - [Const] void constFunc(); -}; - -// Part 2 - -interface StringUser { - void StringUser(); - void StringUser(DOMString str, long i); - void Print(long anotherInteger, DOMString anotherString); - void PrintFloat(float f); -// [Const] DOMString returnAString(); -}; - -interface RefUser { - void RefUser(); - void RefUser(long value); - long getValue([Ref] RefUser b); - [Ref] RefUser getMe(); - [Value] RefUser getCopy(); // must have zero-arg constructor - [Value] StringUser getAnother(); -}; - -interface VoidPointerUser { - void VoidPointerUser(); - - any GetVoidPointer(); - void SetVoidPointer(any ptr); -}; - -[Prefix="Space::"] -interface Inner { - void Inner(); - long get(); -// [Operator="*=", Ref] Inner mul(float x); -// [Operator="[]"] long getAsArray(long x); -// [Operator="+="] void incInPlace([Const, Ref] Inner i); -}; - -[Prefix = "Space::"] -interface InnerUserBase { -}; - -[JSImplementation = "InnerUserBase"] -interface InnerUser { - void InnerUser(); - void Callback(Inner inner); -}; - -enum AnEnum { - "enum_value1", - "enum_value2" -}; - -enum EnumClass_EnumWithinClass { - "EnumClass::e_val" -}; - -enum EnumNamespace_EnumInNamespace { - "EnumNamespace::e_namespace_val" -}; - -interface EnumClass { - void EnumClass(); - - EnumClass_EnumWithinClass GetEnum(); - - EnumNamespace_EnumInNamespace GetEnumFromNameSpace(); -}; - -interface TypeTestClass { - void TypeTestClass(); - - byte ReturnCharMethod(); - void AcceptCharMethod(byte x); - -// octet ReturnUnsignedCharMethod(); -// void AcceptUnsignedCharMethod(octet x); - - unsigned short ReturnUnsignedShortMethod(); - void AcceptUnsignedShortMethod(unsigned short x); - - unsigned long ReturnUnsignedLongMethod(); - void AcceptUnsignedLongMethod(unsigned long x); -}; - -interface StructInArray { - void StructInArray(long attr1, long attr2); - attribute long attr1; - attribute long attr2; -}; - -interface ArrayClass { - void ArrayClass(); -// [BoundsChecked] attribute long[] int_array; -// [Value] attribute StructInArray[] struct_array; -// attribute StructInArray[] struct_ptr_array; -}; - -interface ReceiveArrays { - void ReceiveArrays(); - - void giveMeArrays(float[] vertices, long[] triangles, long num); -}; - -interface StoreArray { - void StoreArray(); - - void setArray([Const] long[] array); - long getArrayValue(long index); -}; - -interface LongLongTypes { -// readonly attribute unsigned long long[] lluArray; - attribute long long ll; -}; - -[NoDelete] -interface ISmallObject { - long getID(long number); -}; - -[JSImplementation="ISmallObject"] -interface JSSmallObject { - void JSSmallObject(); - long getID(long number); -}; - -[NoDelete] -interface IObjectProvider { - ISmallObject getObject(); -}; - -[JSImplementation="IObjectProvider"] -interface JSObjectProvider { - void JSObjectProvider(); - JSSmallObject getObject(); -}; - -interface ObjectFactory { - void ObjectFactory(); - IObjectProvider getProvider(); -}; - -interface ArrayArgumentTest { - void ArrayArgumentTest(); - boolean byteArrayTest([Const] byte[] arg); - boolean domStringTest([Const] DOMString arg); -}; - -[JSImplementation = "ArrayArgumentTest"] -interface JSArrayArgumentTest { - void JSArrayArgumentTest(); - boolean byteArrayTest([Const] byte[] arg); - boolean domStringTest([Const] DOMString arg); -}; \ No newline at end of file diff --git a/example/lib-test/lib-build/src/main/java/BuildLib.java b/example/lib-test/lib-build/src/main/java/BuildLib.java deleted file mode 100644 index cb935942..00000000 --- a/example/lib-test/lib-build/src/main/java/BuildLib.java +++ /dev/null @@ -1,187 +0,0 @@ -import com.github.xpenatan.jparser.builder.BuildMultiTarget; -import com.github.xpenatan.jparser.builder.targets.AndroidTarget; -import com.github.xpenatan.jparser.builder.targets.EmscriptenTarget; -import com.github.xpenatan.jparser.builder.targets.IOSTarget; -import com.github.xpenatan.jparser.builder.targets.LinuxTarget; -import com.github.xpenatan.jparser.builder.targets.MacTarget; -import com.github.xpenatan.jparser.builder.targets.WindowsTarget; -import com.github.xpenatan.jparser.builder.tool.BuildToolListener; -import com.github.xpenatan.jparser.builder.tool.BuildToolOptions; -import com.github.xpenatan.jparser.builder.tool.BuilderTool; -import com.github.xpenatan.jparser.idl.IDLReader; -import java.util.ArrayList; - -public class BuildLib { - - public static void main(String[] args) throws Exception { - String libName = "test"; - String modulePrefix = "lib"; - String basePackage = "lib.test"; - String sourceDir = "/src/main/cpp/source/testLib/src"; - BuildToolOptions op = new BuildToolOptions(libName, basePackage, modulePrefix, sourceDir, args); - BuilderTool.build(op, new BuildToolListener() { - @Override - public void onAddTarget(BuildToolOptions op, IDLReader idlReader, ArrayList targets) { - if(op.teavm) { - targets.add(getTeavmTarget(op, idlReader)); - } - if(op.windows64) { - targets.add(getWindowTarget(op)); - } - if(op.linux64) { - targets.add(getLinuxTarget(op)); - } - if(op.mac64) { - targets.add(getMacTarget(op, false)); - } - if(op.macArm) { - targets.add(getMacTarget(op, true)); - } - if(op.android) { - targets.add(getAndroidTarget(op)); - } - if(op.iOS) { - targets.add(getIOSTarget(op)); - } - } - }); - } - - private static BuildMultiTarget getWindowTarget(BuildToolOptions op) { - BuildMultiTarget multiTarget = new BuildMultiTarget(); - - String libBuildCPPPath = op.getModuleBuildCPPPath(); - - // Make a static library - WindowsTarget compileStaticTarget = new WindowsTarget(); - compileStaticTarget.isStatic = true; - compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); - compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/test/**.cpp"); - multiTarget.add(compileStaticTarget); - - WindowsTarget linkTarget = new WindowsTarget(); - linkTarget.addJNIHeaders(); - linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); - linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/jniglue"); - linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/windows/" + op.libName + "64.a"); - linkTarget.cppInclude.add(libBuildCPPPath + "/src/jniglue/JNIGlue.cpp"); - - multiTarget.add(linkTarget); - return multiTarget; - } - - private static BuildMultiTarget getLinuxTarget(BuildToolOptions op) { - BuildMultiTarget multiTarget = new BuildMultiTarget(); - - String libBuildCPPPath = op.getModuleBuildCPPPath(); - - // Make a static library - LinuxTarget compileStaticTarget = new LinuxTarget(); - compileStaticTarget.isStatic = true; - compileStaticTarget.headerDirs.add("-Isrc/test"); - compileStaticTarget.cppInclude.add("**/src/test/**.cpp"); - multiTarget.add(compileStaticTarget); - - LinuxTarget linkTarget = new LinuxTarget(); - linkTarget.addJNIHeaders(); - linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); - linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/jniglue"); - linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/linux/lib" + op.libName + "64.a"); - linkTarget.cppInclude.add(libBuildCPPPath + "/src/jniglue/JNIGlue.cpp"); - - multiTarget.add(linkTarget); - - return multiTarget; - } - - private static BuildMultiTarget getMacTarget(BuildToolOptions op, boolean isArm) { - BuildMultiTarget multiTarget = new BuildMultiTarget(); - - String libBuildCPPPath = op.getModuleBuildCPPPath(); - - // Make a static library - MacTarget compileStaticTarget = new MacTarget(isArm); - compileStaticTarget.isStatic = true; - compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); - compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/test/**.cpp"); - multiTarget.add(compileStaticTarget); - - MacTarget linkTarget = new MacTarget(isArm); - linkTarget.addJNIHeaders(); - linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); - linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/jniglue"); - - if(isArm) { - linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/mac/arm/lib" + op.libName + "64.a"); - } - else { - linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/mac/lib" + op.libName + "64.a"); - } - linkTarget.cppInclude.add(libBuildCPPPath + "/src/jniglue/JNIGlue.cpp"); - - multiTarget.add(linkTarget); - - return multiTarget; - } - - private static BuildMultiTarget getTeavmTarget(BuildToolOptions op, IDLReader idlReader) { - BuildMultiTarget multiTarget = new BuildMultiTarget(); - - String libBuildCPPPath = op.getModuleBuildCPPPath(); - - // Make a static library - EmscriptenTarget compileStaticTarget = new EmscriptenTarget(idlReader); - compileStaticTarget.isStatic = true; - compileStaticTarget.compileGlueCode = false; - compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); - compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/test/**.cpp"); - multiTarget.add(compileStaticTarget); - - // Compile glue code and link to make js file - EmscriptenTarget linkTarget = new EmscriptenTarget(idlReader); - linkTarget.headerDirs.add("-include" + libBuildCPPPath + "/src/test/CustomCode.h"); - linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/emscripten/" + op.libName + ".a"); - multiTarget.add(linkTarget); - return multiTarget; - } - - private static BuildMultiTarget getAndroidTarget(BuildToolOptions op) { - BuildMultiTarget multiTarget = new BuildMultiTarget(); - - String libBuildCPPPath = op.getModuleBuildCPPPath(); - - AndroidTarget androidTarget = new AndroidTarget(); - androidTarget.addJNIHeaders(); - androidTarget.headerDirs.add(libBuildCPPPath + "/src/test"); - androidTarget.cppInclude.add(libBuildCPPPath + "/src/test/**.cpp"); - - multiTarget.add(androidTarget); - - return multiTarget; - } - - private static BuildMultiTarget getIOSTarget(BuildToolOptions op) { - String libBuildCPPPath = op.getModuleBuildCPPPath(); - // TODO WIP/not working - - BuildMultiTarget multiTarget = new BuildMultiTarget(); - - // Make a static library - IOSTarget compileStaticTarget = new IOSTarget(); - compileStaticTarget.isStatic = true; - compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); - compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/test/**.cpp"); - multiTarget.add(compileStaticTarget); - - IOSTarget linkTarget = new IOSTarget(); - linkTarget.addJNIHeaders(); - linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/test"); - linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/jniglue"); - linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/ios/lib" + op.libName + ".a"); - linkTarget.cppInclude.add(libBuildCPPPath + "/src/jniglue/JNIGlue.cpp"); - - multiTarget.add(linkTarget); - - return multiTarget; - } -} \ No newline at end of file diff --git a/example/lib-test/lib-core/build.gradle.kts b/example/lib-test/lib-core/build.gradle.kts deleted file mode 100644 index eba178a5..00000000 --- a/example/lib-test/lib-core/build.gradle.kts +++ /dev/null @@ -1,19 +0,0 @@ -plugins { - id("java") -} - -dependencies { - if(LibExt.exampleUseRepoLibs) { - implementation("com.github.xpenatan.jParser:loader-core:${LibExt.libVersion}") - } - else { - implementation(project(":jParser:loader:loader-core")) - } -} - -tasks.named("clean") { - doFirst { - val srcPath = "$projectDir/src/main/" - project.delete(files(srcPath)) - } -} \ No newline at end of file diff --git a/example/lib-test/lib-desktop/build.gradle.kts b/example/lib-test/lib-desktop/build.gradle.kts deleted file mode 100644 index b7f5a033..00000000 --- a/example/lib-test/lib-desktop/build.gradle.kts +++ /dev/null @@ -1,34 +0,0 @@ -plugins { - id("java") -} - -val libDir = "${projectDir}/../lib-build/build/c++/libs" -val windowsFile = "$libDir/windows/test64.dll" -val linuxFile = "$libDir/linux/libtest64.so" -val macFile = "$libDir/mac/libtest64.dylib" -val macArmFile = "$libDir/mac/arm/libtestarm64.dylib" - -tasks.jar { - from(windowsFile) - from(linuxFile) - from(macFile) - from(macArmFile) -} - -dependencies { - if(LibExt.exampleUseRepoLibs) { - testImplementation("com.github.xpenatan.jParser:loader-core:${LibExt.libVersion}") - } - else { - testImplementation(project(":jParser:loader:loader-core")) - } - testImplementation(project(":example:lib-test:lib-core")) - testImplementation("junit:junit:${LibExt.jUnitVersion}") -} - -tasks.named("clean") { - doFirst { - val srcPath = "$projectDir/src/main/" - project.delete(files(srcPath)) - } -} \ No newline at end of file diff --git a/example/lib-test/lib-teavm/build.gradle.kts b/example/lib-test/lib-teavm/build.gradle.kts deleted file mode 100644 index a71546f3..00000000 --- a/example/lib-test/lib-teavm/build.gradle.kts +++ /dev/null @@ -1,35 +0,0 @@ -plugins { - id("java") -} - -val emscriptenFile = "$projectDir/../lib-build/build/c++/libs/emscripten/test.wasm.js" - -tasks.jar { - from(emscriptenFile) -} - -dependencies { - implementation("org.teavm:teavm-jso:${LibExt.teaVMVersion}") - implementation(project(":jParser:loader:loader-teavm")) - implementation("org.teavm:teavm-classlib:${LibExt.teaVMVersion}") - - if(LibExt.exampleUseRepoLibs) { - implementation("com.github.xpenatan.jParser:loader-core:${LibExt.libVersion}") - } - else { - implementation(project(":jParser:loader:loader-core")) - } - testImplementation(project(":example:lib-test:lib-core")) - testImplementation("junit:junit:${LibExt.jUnitVersion}") - testImplementation("org.teavm:teavm-core:${LibExt.teaVMVersion}") - testImplementation("org.teavm:teavm-jso-apis:${LibExt.teaVMVersion}") - testImplementation("org.teavm:teavm-classlib:${LibExt.teaVMVersion}") - testImplementation("org.teavm:teavm-junit:${LibExt.teaVMVersion}") -} - -tasks.named("clean") { - doFirst { - val srcPath = "$projectDir/src/main/java/gen" - project.delete(files(srcPath)) - } -} \ No newline at end of file diff --git a/example/lib-test/lib-teavm/src/main/resources/META-INF/gdx-teavm.properties b/example/lib-test/lib-teavm/src/main/resources/META-INF/gdx-teavm.properties deleted file mode 100644 index e69de29b..00000000 diff --git a/example/lib-test/lib-teavm/src/main/resources/META-INF/teavm.properties b/example/lib-test/lib-teavm/src/main/resources/META-INF/teavm.properties deleted file mode 100644 index 22ff4f62..00000000 --- a/example/lib-test/lib-teavm/src/main/resources/META-INF/teavm.properties +++ /dev/null @@ -1 +0,0 @@ -mapPackageHierarchy|gen.com=com diff --git a/settings.gradle.kts b/settings.gradle.kts index 103d305e..c8810e7b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -15,13 +15,6 @@ include(":example:lib:lib-desktop") include(":example:lib:lib-teavm") include(":example:lib:lib-android") -include(":example:lib-test:lib-build") -include(":example:lib-test:lib-base") -include(":example:lib-test:lib-core") -include(":example:lib-test:lib-desktop") -include(":example:lib-test:lib-teavm") -include(":example:lib-test:lib-android") - //include(":example:lib-ext:ext-base") //include(":example:lib-ext:ext-build") //include(":example:lib-ext:ext-core") @@ -32,12 +25,6 @@ include(":example:app:desktop") include(":example:app:teavm") include(":example:app:android") -include(":example:app-test:core") -include(":example:app-test:desktop") -include(":example:app-test:teavm") -include(":example:app-test:android") - - //includeBuild("E:\\Dev\\Projects\\java\\gdx-teavm") { // dependencySubstitution { // substitute(module("com.github.xpenatan.gdx-teavm:backend-teavm")).using(project(":backends:backend-teavm")) From d17bf6aa1f84604c5ed8380867880b631fbe8745 Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 14 Aug 2024 14:34:17 -0300 Subject: [PATCH 055/186] Disable old code --- .gitignore | 3 - .../xpenatan/jparser/example/app/AppTest.java | 170 +---------- .../xpenatan/jparser/example/app/TestLib.java | 11 + example/lib/lib-android/build.gradle.kts | 2 +- .../TestLibLoader.java} | 12 +- .../main/cpp/{exampleLib.idl => TestLib.idl} | 264 +++++++++--------- .../src/DefaultInterface.h | 0 .../src/DefaultParamsClass.cpp | 0 .../src/DefaultParamsClass.h | 0 .../src/InterfaceClass.h | 0 .../src/NormalClass.cpp | 0 .../{exampleLib => TestLib}/src/NormalClass.h | 0 .../src/OperatorClass.cpp | 0 .../src/OperatorClass.h | 0 .../src/ParentClass.cpp | 0 .../{exampleLib => TestLib}/src/ParentClass.h | 0 .../src/ReturnClass.cpp | 0 .../{exampleLib => TestLib}/src/ReturnClass.h | 0 .../{exampleLib => TestLib}/src/TestLib.h | 0 .../src/subpackage/ParamData.cpp | 0 .../src/subpackage/ParamData.h | 0 .../lib/lib-build/src/main/java/BuildLib.java | 60 ++-- example/lib/lib-desktop/build.gradle.kts | 8 +- .../jparser/example/NormalClassTest.java | 5 +- example/lib/lib-teavm/build.gradle.kts | 4 +- 25 files changed, 199 insertions(+), 340 deletions(-) create mode 100644 example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java rename example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/{lib/ExampleLibLoader.java => testlib/TestLibLoader.java} (77%) rename example/lib/lib-build/src/main/cpp/{exampleLib.idl => TestLib.idl} (58%) rename example/lib/lib-build/src/main/cpp/source/{exampleLib => TestLib}/src/DefaultInterface.h (100%) rename example/lib/lib-build/src/main/cpp/source/{exampleLib => TestLib}/src/DefaultParamsClass.cpp (100%) rename example/lib/lib-build/src/main/cpp/source/{exampleLib => TestLib}/src/DefaultParamsClass.h (100%) rename example/lib/lib-build/src/main/cpp/source/{exampleLib => TestLib}/src/InterfaceClass.h (100%) rename example/lib/lib-build/src/main/cpp/source/{exampleLib => TestLib}/src/NormalClass.cpp (100%) rename example/lib/lib-build/src/main/cpp/source/{exampleLib => TestLib}/src/NormalClass.h (100%) rename example/lib/lib-build/src/main/cpp/source/{exampleLib => TestLib}/src/OperatorClass.cpp (100%) rename example/lib/lib-build/src/main/cpp/source/{exampleLib => TestLib}/src/OperatorClass.h (100%) rename example/lib/lib-build/src/main/cpp/source/{exampleLib => TestLib}/src/ParentClass.cpp (100%) rename example/lib/lib-build/src/main/cpp/source/{exampleLib => TestLib}/src/ParentClass.h (100%) rename example/lib/lib-build/src/main/cpp/source/{exampleLib => TestLib}/src/ReturnClass.cpp (100%) rename example/lib/lib-build/src/main/cpp/source/{exampleLib => TestLib}/src/ReturnClass.h (100%) rename example/lib/lib-build/src/main/cpp/source/{exampleLib => TestLib}/src/TestLib.h (100%) rename example/lib/lib-build/src/main/cpp/source/{exampleLib => TestLib}/src/subpackage/ParamData.cpp (100%) rename example/lib/lib-build/src/main/cpp/source/{exampleLib => TestLib}/src/subpackage/ParamData.h (100%) diff --git a/.gitignore b/.gitignore index c9b6bff3..0e47b640 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,3 @@ out/ **/lib/lib-teavm/src/main/java/emu/** **/lib/lib-core/src/main/java/** **/app/android/libs/ -**/lib-test/lib-teavm/src/main/java/emu/** -**/lib-test/lib-core/src/main/java/** -**/app-lib/android/libs/ diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java index 332c3e27..5fb26613 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java @@ -1,21 +1,12 @@ package com.github.xpenatan.jparser.example.app; import com.badlogic.gdx.ApplicationAdapter; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.utils.ScreenUtils; -import com.github.xpenatan.jparser.example.lib.EnumClassWithinClass; -import com.github.xpenatan.jparser.example.lib.EnumInNamespace; -import com.github.xpenatan.jparser.example.lib.EnumLib; -import com.github.xpenatan.jparser.example.lib.EnumTwoLib; -import com.github.xpenatan.jparser.example.lib.EnumWithinClass; -import com.github.xpenatan.jparser.example.lib.ExampleLibLoader; -import com.github.xpenatan.jparser.example.lib.NormalClass; -import com.github.xpenatan.jparser.example.lib.OperatorClass; -import com.github.xpenatan.jparser.example.lib.ReturnClass; -import com.github.xpenatan.jparser.example.lib.idl.helper.IDLFloat; -import com.github.xpenatan.jparser.example.lib.idl.helper.IDLFloatArray; -import com.github.xpenatan.jparser.example.lib.idl.helper.IDLString; +import com.github.xpenatan.jparser.example.testlib.TestLibLoader; public class AppTest extends ApplicationAdapter { private boolean init = false; @@ -23,13 +14,13 @@ public class AppTest extends ApplicationAdapter { private SpriteBatch batch; private BitmapFont font; - private int a1 = 1; - private int b1 = 1; - private int ret1; + boolean testPass = false; + + Color color = Color.GRAY; @Override public void create() { - ExampleLibLoader.init(new Runnable() { + TestLibLoader.init(new Runnable() { @Override public void run() { init = true; @@ -43,156 +34,17 @@ public void run() { @Override public void render() { - ScreenUtils.clear(0.4f, 0.4f, 0.4f, 1); + ScreenUtils.clear(color); if(init) { init = false; - initLib(); + testPass = TestLib.test(); + color = testPass ? Color.GREEN : Color.RED; return; } batch.begin(); - font.draw(batch, "addIntValue " + a1 + " + " + b1 + " = " + ret1, 100, 100); + font.draw(batch, "Test Pass " + testPass, 100, Gdx.graphics.getHeight()/2f); batch.end(); } - - private void initLib() { - NormalClass normalClass = new NormalClass(); - - IDLString string = new IDLString(); - - string.append("MY TEXT"); - string.append(" HELLO"); - - String text = string.c_str(); - - System.out.println("String: " + text); - - normalClass.setString(string); - - IDLString retString = normalClass.getString(); - System.out.println("retString: " + retString.c_str()); - IDLString retStringValue = normalClass.getStringValue(); - System.out.println("retStringValue: " + retStringValue.c_str()); - - int version = normalClass.getVersion(); - System.out.println("Version " + version); - - ret1 = normalClass.addIntValue(a1, b1); - System.out.println("addIntValue " + a1 + " + " + b1 + " = " + ret1); - - IDLFloatArray array = new IDLFloatArray(1); - array.setValue(0, 10); - float value = array.getValue(0); - System.out.println("VALUE: " + value); - - System.out.println("ENUM FIRST: " + EnumLib.FIRST); - System.out.println("ENUM SECOND: " + EnumLib.SECOND); - System.out.println("ENUMPARAM FIRST: " + normalClass.enumParam(EnumLib.FIRST)); - System.out.println("ENUMPARAM SECOND: " + normalClass.enumParam(EnumLib.SECOND)); - normalClass.enumVoidParam(EnumLib.FIRST); - System.out.println("ENUM Return FIRST: " + normalClass.enumReturn(1)); - System.out.println("ENUM Return SECOND: " + normalClass.enumReturn(2)); - System.out.println("ENUM Return DEFAULT: " + normalClass.enumReturn(99)); - System.out.println("EnumWithinClass e_val: " + EnumWithinClass.e_val); - System.out.println("EnumClassWithinClass testEnum: " + EnumClassWithinClass.testEnum); - System.out.println("EnumInNamespace e_namespace_val: " + EnumInNamespace.e_namespace_val); - - ReturnClass returnValueObject = normalClass.getReturnValueObject(); - System.out.println("returnValueObject: " + returnValueObject.get_value()); - - normalClass.printText(10, "printText HELLO"); - IDLFloat floatArray = IDLFloat.TMP_1; - long pointer = floatArray.getPointer(); - System.out.println("pointer: " + pointer); - normalClass.setArray(floatArray); - System.out.println("setArray: " + floatArray.getValue()); - System.out.println("EnumTwoLib THIRD: " + EnumTwoLib.EnumTwoLib_THIRD); - System.out.println("EnumTwoLib FOURTH: " + EnumTwoLib.EnumTwoLib_FOURTH); - System.out.println("NormalClass.subIntValue: " + NormalClass.subIntValue(2, 1)); - - OperatorClass operatorClass1 = new OperatorClass(); - operatorClass1.set_value(41); - OperatorClass operatorClass2 = new OperatorClass(); - operatorClass2.set_value(3); - operatorClass1.copy(operatorClass2); - - System.out.println("operatorClass1 copy: " + operatorClass1.get_value()); - - testPrimitive(); - testArray(normalClass); - -// CustomLib.print(); - } - - private void testPrimitive() { - System.out.println("########## TESTING ATTRIBUTES ##########"); - - NormalClass.set_hiddenInt_static(22); - int hiddenIntStatic = NormalClass.get_hiddenInt_static(); - System.out.println("hiddenIntStatic: " + hiddenIntStatic); - - ReturnClass nullPointerReturnClassStatic = NormalClass.get_nullPointerReturnClass_static(); - System.out.println("nullPointerReturnClassStatic: " + nullPointerReturnClassStatic); - -// ReturnClass pointerReturnClassStatic = NormalClass.get_pointerReturnClass_static(); -// pointerReturnClassStatic.set_value(51); -// System.out.println("pointerReturnClassStatic: " + pointerReturnClassStatic.get_value()); - - ReturnClass valueReturnClassStatic = NormalClass.get_valueReturnClass_static(); - System.out.println("valueReturnClassStatic: " + valueReturnClassStatic.get_value()); - - NormalClass normalClass = new NormalClass(); - - normalClass.set_hiddenInt(4); - int hiddenInt = normalClass.get_hiddenInt(); - System.out.println("hiddenInt: " + hiddenInt); - - ReturnClass pointerReturnClass = normalClass.get_pointerReturnClass(); - pointerReturnClass.set_value(11); - System.out.println("pointerReturnClass: " + pointerReturnClass.get_value()); - - ReturnClass valueReturnClass = normalClass.get_valueReturnClass(); - valueReturnClass.set_value(12); - System.out.println("valueReturnClass: " + valueReturnClass.get_value()); - - ReturnClass nullPointerReturnClass = normalClass.get_nullPointerReturnClass(); - System.out.println("nullPointerReturnClass: " + nullPointerReturnClass); - } - - private void testArray(NormalClass normalClass) { - System.out.println("set intArray"); - normalClass.set_intArray(0, 1); - normalClass.set_intArray(1, 2); - normalClass.set_intArray(2, 3); - System.out.println("get intArray"); - int intArray0 = normalClass.get_intArray(0); - int intArray1 = normalClass.get_intArray(1); - int intArray2 = normalClass.get_intArray(2); - System.out.println("intArray0: " + intArray0); - System.out.println("intArray1: " + intArray1); - System.out.println("intArray2: " + intArray2); - - //Object value is updated from 10 to 11 even after getting the pointer - ReturnClass pointerClass1 = new ReturnClass(); - pointerClass1.set_value(10); - normalClass.set_pointerArray(0, pointerClass1); - ReturnClass pointerObject = normalClass.get_pointerArray(0); - float valuePointer = pointerObject.get_value(); - System.out.println("pointerClass1: " + valuePointer); - pointerClass1.set_value(11); - float valuePointerUpdated = pointerObject.get_value(); - System.out.println("pointerClass1 updated: " + valuePointerUpdated); - - //Object value is not updated from 10 to 11 because a object copy is made - ReturnClass valueClass1 = new ReturnClass(); - valueClass1.set_value(10); - normalClass.set_valueArray(0, valueClass1); - ReturnClass valueObject = normalClass.get_valueArray(0); - valueClass1.set_value(11); - float valueObj = valueObject.get_value(); - System.out.println("valueClass1: " + valueObj); - float valueObjUpdated = valueObject.get_value(); - System.out.println("valueClass1 updated: " + valueObjUpdated); - } } \ No newline at end of file diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java new file mode 100644 index 00000000..076c99e7 --- /dev/null +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java @@ -0,0 +1,11 @@ +package com.github.xpenatan.jparser.example.app; + +public class TestLib { + + public static boolean test() { + + + + return false; + } +} diff --git a/example/lib/lib-android/build.gradle.kts b/example/lib/lib-android/build.gradle.kts index d332eca6..a407ceac 100644 --- a/example/lib/lib-android/build.gradle.kts +++ b/example/lib/lib-android/build.gradle.kts @@ -6,7 +6,7 @@ plugins { group = "jparser.lib.android" android { - namespace = "com.github.xpenatan.jparser.example.lib" + namespace = "com.github.xpenatan.jparser.example.testlib" compileSdk = 33 defaultConfig { diff --git a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/lib/ExampleLibLoader.java b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/TestLibLoader.java similarity index 77% rename from example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/lib/ExampleLibLoader.java rename to example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/TestLibLoader.java index 99dc64a2..6f6c115e 100644 --- a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/lib/ExampleLibLoader.java +++ b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/TestLibLoader.java @@ -1,8 +1,10 @@ -package com.github.xpenatan.jparser.example.lib; +package com.github.xpenatan.jparser.example.testlib; import com.github.xpenatan.jparser.loader.JParserLibraryLoader; -public class ExampleLibLoader { +public class TestLibLoader { + + public static final String LIB_NAME = "TestLib"; /*[-JNI;-NATIVE] #include "CustomCode.h" @@ -20,13 +22,13 @@ public static void init(Runnable onSuccess) { JParserLibraryLoader libraryLoader = new JParserLibraryLoader(); OnInitFunction onInitFunction = () -> onSuccess.run(); setOnLoadInit(onInitFunction); - libraryLoader.load("exampleLib.wasm", isSuccess -> {}); + libraryLoader.load(LIB_NAME + ".wasm", isSuccess -> {}); } */ public static void init(Runnable onSuccess) { JParserLibraryLoader libraryLoader = new JParserLibraryLoader(); - libraryLoader.load("exampleLib", isSuccess -> { + libraryLoader.load(LIB_NAME, isSuccess -> { if(isSuccess) { onSuccess.run(); } @@ -34,7 +36,7 @@ public static void init(Runnable onSuccess) { } /*[-TEAVM;-REPLACE] - @org.teavm.jso.JSBody(params = { "onInitFunction" }, script = "window.exampleLibOnInit = onInitFunction;") + @org.teavm.jso.JSBody(params = { "onInitFunction" }, script = "window.TestLibOnInit = onInitFunction;") private static native void setOnLoadInit(OnInitFunction onInitFunction); */ /*[-JNI;-REMOVE] */ diff --git a/example/lib/lib-build/src/main/cpp/exampleLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl similarity index 58% rename from example/lib/lib-build/src/main/cpp/exampleLib.idl rename to example/lib/lib-build/src/main/cpp/TestLib.idl index 4654cf8c..af5113d1 100644 --- a/example/lib/lib-build/src/main/cpp/exampleLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -148,135 +148,135 @@ enum TestEnumLib { // ########################################## -interface ParentClass { - float addFloatValue(float a, float b); - boolean invertBoolean(boolean value); -}; - -interface NormalClass { - [BoundsChecked] attribute long[] intArray; - [Value] attribute ReturnClass[] valueArray; - attribute ReturnClass[] pointerArray; - attribute long hiddenInt; - [Value] attribute ReturnClass valueReturnClass; - attribute ReturnClass pointerReturnClass; - attribute ReturnClass nullPointerReturnClass; - - static attribute long hiddenInt_static; - [Value] static attribute ReturnClass valueReturnClass_static; - static attribute ReturnClass pointerReturnClass_static; - static attribute ReturnClass nullPointerReturnClass_static; - - void NormalClass(); - void NormalClass(long c, [Ref]ParamData refParamClass); - void NormalClass(EnumInNamespace nameSpaceEnum); - - long getVersion(); -// Emscripten don't allow param by value -// void NormalClass(ParamData pointerParamData, [Ref]ParamData refParamData, [Value]ParamData valueParamData); - -// void setString(DOMString text); -// static DOMString addString(DOMString text); -// [Value] static ReturnClass getStaticReturnValueClass(ParamData paramData); - [Value]ReturnClass getReturnValueClass(ParamData paramData); - - static long subIntValue(long a, long b, optional long subValue); - long addIntValue(long a, long b); - [Ref]ReturnClass getReturnRefClass(); - [Value]ReturnClass getReturnValueObject(); -// ReturnClass getReturnPointerClass(); -// ReturnClass getReturnNullPointerClass(); - void refParam([Ref]ParamData refParamOne, [Ref]ParamData refParamTwo, [Ref]ParamData refParamThree); -// void pointerParam(ParamData paramData); - - // Emscripten don't allow param by value -// void valueParam([Value]ParamData paramData); - -// void addIntArrayItems(long [] array); - - void callInterface([Ref]InterfaceClass obj); - - long enumParam(EnumLib value); - - void enumVoidParam(EnumLib value); - - EnumLib enumReturn(long value); - - boolean printText(long dummyParam, [Const]DOMString text); - - void setArray(float[] array); - - void setString([Ref] IDLString text); - [Ref] IDLString getString(); - [Value] IDLString getStringValue(); - - void setVoidParam(any param); - any getVoidParam(); -}; -NormalClass implements ParentClass; - -interface DefaultParamsClass { - void DefaultParamsClass(long a, long b, optional float c, optional float d); - - void defaultMethodParams(long a, long b, optional float c, optional float d); -}; - -[NoDelete] -interface ReturnClass { - void ReturnClass(); - - attribute float value; - - [Operator="=", Ref] ReturnClass copy([Ref]ReturnClass value); -}; - -interface OperatorClass { - void OperatorClass(); - - attribute float value; - - [Operator="=", Ref] OperatorClass copy([Ref]OperatorClass value); -}; - -interface ParamData { - void ParamData(); - attribute long intData; - attribute float floatData; -}; - -interface InterfaceClass { - void onParamCall([Ref]ParamData data); -}; - -[JSImplementation="InterfaceClass"] -interface InterfaceClassImpl { - void InterfaceClassImpl(); - [Const] void onParamCall([Ref]ParamData data); -}; - -interface DefaultInterface { - void DefaultInterface(); -}; -DefaultInterface implements InterfaceClass; - -enum EnumLib { - "FIRST", - "SECOND" -}; - -enum EnumTwoLib { - "EnumTwoLib_THIRD", - "EnumTwoLib_FOURTH" -}; - -enum EnumWithinClass { - "NormalClass::e_val" -}; - -enum EnumClassWithinClass { - "EnumClassWithinClass::testEnum" -}; - -enum EnumInNamespace { - "EnumInNamespace::e_namespace_val" -}; \ No newline at end of file +//interface ParentClass { +// float addFloatValue(float a, float b); +// boolean invertBoolean(boolean value); +//}; +// +//interface NormalClass { +// [BoundsChecked] attribute long[] intArray; +// [Value] attribute ReturnClass[] valueArray; +// attribute ReturnClass[] pointerArray; +// attribute long hiddenInt; +// [Value] attribute ReturnClass valueReturnClass; +// attribute ReturnClass pointerReturnClass; +// attribute ReturnClass nullPointerReturnClass; +// +// static attribute long hiddenInt_static; +// [Value] static attribute ReturnClass valueReturnClass_static; +// static attribute ReturnClass pointerReturnClass_static; +// static attribute ReturnClass nullPointerReturnClass_static; +// +// void NormalClass(); +// void NormalClass(long c, [Ref]ParamData refParamClass); +// void NormalClass(EnumInNamespace nameSpaceEnum); +// +// long getVersion(); +//// Emscripten don't allow param by value +//// void NormalClass(ParamData pointerParamData, [Ref]ParamData refParamData, [Value]ParamData valueParamData); +// +//// void setString(DOMString text); +//// static DOMString addString(DOMString text); +//// [Value] static ReturnClass getStaticReturnValueClass(ParamData paramData); +// [Value]ReturnClass getReturnValueClass(ParamData paramData); +// +// static long subIntValue(long a, long b, optional long subValue); +// long addIntValue(long a, long b); +// [Ref]ReturnClass getReturnRefClass(); +// [Value]ReturnClass getReturnValueObject(); +//// ReturnClass getReturnPointerClass(); +//// ReturnClass getReturnNullPointerClass(); +// void refParam([Ref]ParamData refParamOne, [Ref]ParamData refParamTwo, [Ref]ParamData refParamThree); +//// void pointerParam(ParamData paramData); +// +// // Emscripten don't allow param by value +//// void valueParam([Value]ParamData paramData); +// +//// void addIntArrayItems(long [] array); +// +// void callInterface([Ref]InterfaceClass obj); +// +// long enumParam(EnumLib value); +// +// void enumVoidParam(EnumLib value); +// +// EnumLib enumReturn(long value); +// +// boolean printText(long dummyParam, [Const]DOMString text); +// +// void setArray(float[] array); +// +// void setString([Ref] IDLString text); +// [Ref] IDLString getString(); +// [Value] IDLString getStringValue(); +// +// void setVoidParam(any param); +// any getVoidParam(); +//}; +//NormalClass implements ParentClass; +// +//interface DefaultParamsClass { +// void DefaultParamsClass(long a, long b, optional float c, optional float d); +// +// void defaultMethodParams(long a, long b, optional float c, optional float d); +//}; +// +//[NoDelete] +//interface ReturnClass { +// void ReturnClass(); +// +// attribute float value; +// +// [Operator="=", Ref] ReturnClass copy([Ref]ReturnClass value); +//}; +// +//interface OperatorClass { +// void OperatorClass(); +// +// attribute float value; +// +// [Operator="=", Ref] OperatorClass copy([Ref]OperatorClass value); +//}; +// +//interface ParamData { +// void ParamData(); +// attribute long intData; +// attribute float floatData; +//}; +// +//interface InterfaceClass { +// void onParamCall([Ref]ParamData data); +//}; +// +//[JSImplementation="InterfaceClass"] +//interface InterfaceClassImpl { +// void InterfaceClassImpl(); +// [Const] void onParamCall([Ref]ParamData data); +//}; +// +//interface DefaultInterface { +// void DefaultInterface(); +//}; +//DefaultInterface implements InterfaceClass; +// +//enum EnumLib { +// "FIRST", +// "SECOND" +//}; +// +//enum EnumTwoLib { +// "EnumTwoLib_THIRD", +// "EnumTwoLib_FOURTH" +//}; +// +//enum EnumWithinClass { +// "NormalClass::e_val" +//}; +// +//enum EnumClassWithinClass { +// "EnumClassWithinClass::testEnum" +//}; +// +//enum EnumInNamespace { +// "EnumInNamespace::e_namespace_val" +//}; \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/DefaultInterface.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultInterface.h similarity index 100% rename from example/lib/lib-build/src/main/cpp/source/exampleLib/src/DefaultInterface.h rename to example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultInterface.h diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/DefaultParamsClass.cpp b/example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultParamsClass.cpp similarity index 100% rename from example/lib/lib-build/src/main/cpp/source/exampleLib/src/DefaultParamsClass.cpp rename to example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultParamsClass.cpp diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/DefaultParamsClass.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultParamsClass.h similarity index 100% rename from example/lib/lib-build/src/main/cpp/source/exampleLib/src/DefaultParamsClass.h rename to example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultParamsClass.h diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/InterfaceClass.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/InterfaceClass.h similarity index 100% rename from example/lib/lib-build/src/main/cpp/source/exampleLib/src/InterfaceClass.h rename to example/lib/lib-build/src/main/cpp/source/TestLib/src/InterfaceClass.h diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/NormalClass.cpp b/example/lib/lib-build/src/main/cpp/source/TestLib/src/NormalClass.cpp similarity index 100% rename from example/lib/lib-build/src/main/cpp/source/exampleLib/src/NormalClass.cpp rename to example/lib/lib-build/src/main/cpp/source/TestLib/src/NormalClass.cpp diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/NormalClass.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/NormalClass.h similarity index 100% rename from example/lib/lib-build/src/main/cpp/source/exampleLib/src/NormalClass.h rename to example/lib/lib-build/src/main/cpp/source/TestLib/src/NormalClass.h diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/OperatorClass.cpp b/example/lib/lib-build/src/main/cpp/source/TestLib/src/OperatorClass.cpp similarity index 100% rename from example/lib/lib-build/src/main/cpp/source/exampleLib/src/OperatorClass.cpp rename to example/lib/lib-build/src/main/cpp/source/TestLib/src/OperatorClass.cpp diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/OperatorClass.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/OperatorClass.h similarity index 100% rename from example/lib/lib-build/src/main/cpp/source/exampleLib/src/OperatorClass.h rename to example/lib/lib-build/src/main/cpp/source/TestLib/src/OperatorClass.h diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/ParentClass.cpp b/example/lib/lib-build/src/main/cpp/source/TestLib/src/ParentClass.cpp similarity index 100% rename from example/lib/lib-build/src/main/cpp/source/exampleLib/src/ParentClass.cpp rename to example/lib/lib-build/src/main/cpp/source/TestLib/src/ParentClass.cpp diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/ParentClass.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/ParentClass.h similarity index 100% rename from example/lib/lib-build/src/main/cpp/source/exampleLib/src/ParentClass.h rename to example/lib/lib-build/src/main/cpp/source/TestLib/src/ParentClass.h diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/ReturnClass.cpp b/example/lib/lib-build/src/main/cpp/source/TestLib/src/ReturnClass.cpp similarity index 100% rename from example/lib/lib-build/src/main/cpp/source/exampleLib/src/ReturnClass.cpp rename to example/lib/lib-build/src/main/cpp/source/TestLib/src/ReturnClass.cpp diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/ReturnClass.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/ReturnClass.h similarity index 100% rename from example/lib/lib-build/src/main/cpp/source/exampleLib/src/ReturnClass.h rename to example/lib/lib-build/src/main/cpp/source/TestLib/src/ReturnClass.h diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h similarity index 100% rename from example/lib/lib-build/src/main/cpp/source/exampleLib/src/TestLib.h rename to example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/subpackage/ParamData.cpp b/example/lib/lib-build/src/main/cpp/source/TestLib/src/subpackage/ParamData.cpp similarity index 100% rename from example/lib/lib-build/src/main/cpp/source/exampleLib/src/subpackage/ParamData.cpp rename to example/lib/lib-build/src/main/cpp/source/TestLib/src/subpackage/ParamData.cpp diff --git a/example/lib/lib-build/src/main/cpp/source/exampleLib/src/subpackage/ParamData.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/subpackage/ParamData.h similarity index 100% rename from example/lib/lib-build/src/main/cpp/source/exampleLib/src/subpackage/ParamData.h rename to example/lib/lib-build/src/main/cpp/source/TestLib/src/subpackage/ParamData.h diff --git a/example/lib/lib-build/src/main/java/BuildLib.java b/example/lib/lib-build/src/main/java/BuildLib.java index 16d39d46..4263bfbd 100644 --- a/example/lib/lib-build/src/main/java/BuildLib.java +++ b/example/lib/lib-build/src/main/java/BuildLib.java @@ -14,10 +14,10 @@ public class BuildLib { public static void main(String[] args) throws Exception { - String libName = "exampleLib"; + String libName = "TestLib"; String modulePrefix = "lib"; - String basePackage = "com.github.xpenatan.jparser.example.lib"; - String sourceDir = "/src/main/cpp/source/exampleLib/src"; + String basePackage = "com.github.xpenatan.jparser.example.testlib"; + String sourceDir = "/src/main/cpp/source/TestLib/src"; BuildToolOptions op = new BuildToolOptions(libName, basePackage, modulePrefix, sourceDir, args); BuilderTool.build(op, new BuildToolListener() { @Override @@ -55,13 +55,13 @@ private static BuildMultiTarget getWindowTarget(BuildToolOptions op) { // Make a static library WindowsTarget compileStaticTarget = new WindowsTarget(); compileStaticTarget.isStatic = true; - compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/exampleLib"); - compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/exampleLib/**.cpp"); + compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/TestLib"); + compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/TestLib/**.cpp"); multiTarget.add(compileStaticTarget); WindowsTarget linkTarget = new WindowsTarget(); linkTarget.addJNIHeaders(); - linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/exampleLib"); + linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/TestLib"); linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/jniglue"); linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/windows/" + op.libName + "64.a"); linkTarget.cppInclude.add(libBuildCPPPath + "/src/jniglue/JNIGlue.cpp"); @@ -78,13 +78,13 @@ private static BuildMultiTarget getLinuxTarget(BuildToolOptions op) { // Make a static library LinuxTarget compileStaticTarget = new LinuxTarget(); compileStaticTarget.isStatic = true; - compileStaticTarget.headerDirs.add("-Isrc/exampleLib"); - compileStaticTarget.cppInclude.add("**/src/exampleLib/**.cpp"); + compileStaticTarget.headerDirs.add("-Isrc/TestLib"); + compileStaticTarget.cppInclude.add("**/src/TestLib/**.cpp"); multiTarget.add(compileStaticTarget); LinuxTarget linkTarget = new LinuxTarget(); linkTarget.addJNIHeaders(); - linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/exampleLib"); + linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/TestLib"); linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/jniglue"); linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/linux/lib" + op.libName + "64.a"); linkTarget.cppInclude.add(libBuildCPPPath + "/src/jniglue/JNIGlue.cpp"); @@ -102,13 +102,13 @@ private static BuildMultiTarget getMacTarget(BuildToolOptions op, boolean isArm) // Make a static library MacTarget compileStaticTarget = new MacTarget(isArm); compileStaticTarget.isStatic = true; - compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/exampleLib"); - compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/exampleLib/**.cpp"); + compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/TestLib"); + compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/TestLib/**.cpp"); multiTarget.add(compileStaticTarget); MacTarget linkTarget = new MacTarget(isArm); linkTarget.addJNIHeaders(); - linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/exampleLib"); + linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/TestLib"); linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/jniglue"); if(isArm) { @@ -134,9 +134,9 @@ private static BuildMultiTarget getTeavmTarget(BuildToolOptions op, IDLReader id if(buildType == 0) { // // Compile and create a js file // EmscriptenTarget emscriptenTarget = new EmscriptenTarget(idlReader); -// emscriptenTarget.headerDirs.add("-Isrc/exampleLib"); -// emscriptenTarget.headerDirs.add("-includesrc/exampleLib/CustomCode.h"); -// emscriptenTarget.cppInclude.add("**/src/exampleLib/**.cpp"); +// emscriptenTarget.headerDirs.add("-Isrc/TestLib"); +// emscriptenTarget.headerDirs.add("-includesrc/TestLib/CustomCode.h"); +// emscriptenTarget.cppInclude.add("**/src/TestLib/**.cpp"); // multiTarget.add(emscriptenTarget); } else if(buildType == 1) { @@ -144,23 +144,23 @@ else if(buildType == 1) { EmscriptenTarget compileStaticTarget = new EmscriptenTarget(idlReader); compileStaticTarget.isStatic = true; compileStaticTarget.compileGlueCode = false; - compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/exampleLib"); - compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/exampleLib/**.cpp"); + compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/TestLib"); + compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/TestLib/**.cpp"); multiTarget.add(compileStaticTarget); // Compile glue code and link to make js file EmscriptenTarget linkTarget = new EmscriptenTarget(idlReader); - linkTarget.headerDirs.add("-include" + libBuildCPPPath + "/src/exampleLib/CustomCode.h"); + linkTarget.headerDirs.add("-include" + libBuildCPPPath + "/src/TestLib/CustomCode.h"); linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/emscripten/" + op.libName + ".a"); multiTarget.add(linkTarget); } else if(buildType == 2) { // // Make lib as a side module/dynamic linking // EmscriptenLibTarget sideTarget = new EmscriptenLibTarget(); -// sideTarget.libName = "exampleLibside"; -// sideTarget.headerDirs.add("-Isrc/exampleLib"); -// sideTarget.headerDirs.add("-includesrc/exampleLib/CustomCode.h"); -// sideTarget.cppInclude.add("**/src/exampleLib/**.cpp"); +// sideTarget.libName = "TestLibside"; +// sideTarget.headerDirs.add("-Isrc/TestLib"); +// sideTarget.headerDirs.add("-includesrc/TestLib/CustomCode.h"); +// sideTarget.cppInclude.add("**/src/TestLib/**.cpp"); // sideTarget.cppFlags.add("-fPIC"); // sideTarget.cppFlags.add("-sEXPORT_ALL=1"); // sideTarget.linkerFlags.add("-v"); @@ -172,13 +172,13 @@ else if(buildType == 2) { // // // Make lib as a main module // EmscriptenTarget mainTarget = new EmscriptenTarget(idlReader); -// mainTarget.headerDirs.add("-Isrc/exampleLib"); -// mainTarget.headerDirs.add("-includesrc/exampleLib/CustomCode.h"); +// mainTarget.headerDirs.add("-Isrc/TestLib"); +// mainTarget.headerDirs.add("-includesrc/TestLib/CustomCode.h"); // mainTarget.cppFlags.add("-fPIC"); // mainTarget.linkerFlags.add("-sMAIN_MODULE=2"); // mainTarget.linkerFlags.add("-fPIC"); // mainTarget.linkerFlags.add("-ERROR_ON_UNDEFINED_SYMBOLS=0"); -// mainTarget.linkerFlags.add("../../libs/emscripten/exampleLibside.wasm"); +// mainTarget.linkerFlags.add("../../libs/emscripten/TestLibside.wasm"); // multiTarget.add(mainTarget); } return multiTarget; @@ -191,8 +191,8 @@ private static BuildMultiTarget getAndroidTarget(BuildToolOptions op) { AndroidTarget androidTarget = new AndroidTarget(); androidTarget.addJNIHeaders(); - androidTarget.headerDirs.add(libBuildCPPPath + "/src/exampleLib"); - androidTarget.cppInclude.add(libBuildCPPPath + "/src/exampleLib/**.cpp"); + androidTarget.headerDirs.add(libBuildCPPPath + "/src/TestLib"); + androidTarget.cppInclude.add(libBuildCPPPath + "/src/TestLib/**.cpp"); multiTarget.add(androidTarget); @@ -208,13 +208,13 @@ private static BuildMultiTarget getIOSTarget(BuildToolOptions op) { // Make a static library IOSTarget compileStaticTarget = new IOSTarget(); compileStaticTarget.isStatic = true; - compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/exampleLib"); - compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/exampleLib/**.cpp"); + compileStaticTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/TestLib"); + compileStaticTarget.cppInclude.add(libBuildCPPPath + "/src/TestLib/**.cpp"); multiTarget.add(compileStaticTarget); IOSTarget linkTarget = new IOSTarget(); linkTarget.addJNIHeaders(); - linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/exampleLib"); + linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/TestLib"); linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/jniglue"); linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/ios/lib" + op.libName + ".a"); linkTarget.cppInclude.add(libBuildCPPPath + "/src/jniglue/JNIGlue.cpp"); diff --git a/example/lib/lib-desktop/build.gradle.kts b/example/lib/lib-desktop/build.gradle.kts index 85cd59ba..6342fd98 100644 --- a/example/lib/lib-desktop/build.gradle.kts +++ b/example/lib/lib-desktop/build.gradle.kts @@ -3,10 +3,10 @@ plugins { } val libDir = "${projectDir}/../lib-build/build/c++/libs" -val windowsFile = "$libDir/windows/exampleLib64.dll" -val linuxFile = "$libDir/linux/libexampleLib64.so" -val macFile = "$libDir/mac/libexampleLib64.dylib" -val macArmFile = "$libDir/mac/arm/libexampleLibarm64.dylib" +val windowsFile = "$libDir/windows/TestLib64.dll" +val linuxFile = "$libDir/linux/libTestLib64.so" +val macFile = "$libDir/mac/libTestLib64.dylib" +val macArmFile = "$libDir/mac/arm/libTestLibarm64.dylib" tasks.jar { from(windowsFile) diff --git a/example/lib/lib-desktop/src/test/java/com/github/xpenatan/jparser/example/NormalClassTest.java b/example/lib/lib-desktop/src/test/java/com/github/xpenatan/jparser/example/NormalClassTest.java index adfbb717..9f38f5dd 100644 --- a/example/lib/lib-desktop/src/test/java/com/github/xpenatan/jparser/example/NormalClassTest.java +++ b/example/lib/lib-desktop/src/test/java/com/github/xpenatan/jparser/example/NormalClassTest.java @@ -1,9 +1,6 @@ package com.github.xpenatan.jparser.example; -import com.github.xpenatan.jparser.example.lib.NormalClass; -import com.github.xpenatan.jparser.loader.JParserLibraryLoader; -import org.junit.BeforeClass; -import org.junit.Test; +import com.github.xpenatan.jparser.example.testlib.NormalClass; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; diff --git a/example/lib/lib-teavm/build.gradle.kts b/example/lib/lib-teavm/build.gradle.kts index 45c5b019..9abedb40 100644 --- a/example/lib/lib-teavm/build.gradle.kts +++ b/example/lib/lib-teavm/build.gradle.kts @@ -2,8 +2,8 @@ plugins { id("java") } -val emscriptenFile = "$projectDir/../lib-build/build/c++/libs/emscripten/exampleLib.wasm.js" -val emscriptenSideFile = "$projectDir/../lib-build/build/c++/libs/emscripten/exampleLibside.wasm" +val emscriptenFile = "$projectDir/../lib-build/build/c++/libs/emscripten/TestLib.wasm.js" +val emscriptenSideFile = "$projectDir/../lib-build/build/c++/libs/emscripten/TestLibside.wasm" tasks.jar { from(emscriptenFile, emscriptenSideFile) From 293f5a89336309b72a95251e3e1045bb10cd15ce Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 14 Aug 2024 15:09:42 -0300 Subject: [PATCH 056/186] Prepare test --- .../xpenatan/jparser/example/app/TestLib.java | 56 ++++++++++++++++++- .../lib/lib-build/src/main/cpp/TestLib.idl | 30 +++++----- 2 files changed, 70 insertions(+), 16 deletions(-) diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java index 076c99e7..b11a089b 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java @@ -3,9 +3,63 @@ public class TestLib { public static boolean test() { + boolean constructorTest = testConstructorClass(); + boolean attributeTest = testAttributeClass(); + boolean staticAttributeTest = testStaticAttributeClass(); + boolean attributeArrayTest = testAttributeArrayClass(); + boolean methodTest = testMethodClass(); + boolean staticMethodTest = testStaticMethodClass(); + boolean callbackTest = testCallbackClass(); + System.out.println("constructorTest: " + constructorTest); + System.out.println("attributeTest: " + attributeTest); + System.out.println("staticAttributeTest: " + staticAttributeTest); + System.out.println("attributeArrayTest: " + attributeArrayTest); + System.out.println("methodTest: " + methodTest); + System.out.println("staticMethodTest: " + staticMethodTest); + System.out.println("callbackTest: " + callbackTest); + return attributeTest && attributeArrayTest; + } + + private static boolean testConstructorClass() { + + + return false; + } + + private static boolean testAttributeClass() { + + + return false; + } + + private static boolean testStaticAttributeClass() { + + + return false; + } + + private static boolean testAttributeArrayClass() { + + + return false; + } + + private static boolean testMethodClass() { + + + return false; + } + + private static boolean testStaticMethodClass() { + + + return false; + } + + private static boolean testCallbackClass() { return false; } -} +} \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index af5113d1..c69f66ad 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -4,14 +4,13 @@ interface TestObjectClass { attribute float floatValue01; }; -interface TestAttributeArrayClass { - void TestAttributeArrayClass(); - [BoundsChecked] attribute long[] intArray; - attribute float[] floatArray; - attribute byte[] byteArray; - attribute boolean[] boolArray; - [Value] attribute TestObjectClass[] valueObjectArray; - attribute TestObjectClass[] pointerObjectArray; +interface TestConstructorClass { + [Value] attribute IDLString strValue01; + + void TestConstructorClass(long intValue01); + void TestConstructorClass(float floatValue, [Const] DOMString strValue01); + void TestConstructorClass(long intValue01, long intValue02, float floatValue01, float floatValue02, optional boolean boolValue01); + void TestConstructorClass(long intValue01, long[] intArray, float[] floatArray); }; interface TestAttributeClass { @@ -37,13 +36,14 @@ interface TestStaticAttributeClass { static attribute boolean staticBoolValue01; }; -interface TestConstructorClass { - [Value] attribute IDLString strValue01; - - void TestConstructorClass(long intValue01); - void TestConstructorClass(float floatValue, [Const] DOMString strValue01); - void TestConstructorClass(long intValue01, long intValue02, float floatValue01, float floatValue02, optional boolean boolValue01); - void TestConstructorClass(long intValue01, long[] intArray, float[] floatArray); +interface TestAttributeArrayClass { + void TestAttributeArrayClass(); + [BoundsChecked] attribute long[] intArray; + attribute float[] floatArray; + attribute byte[] byteArray; + attribute boolean[] boolArray; + [Value] attribute TestObjectClass[] valueObjectArray; + attribute TestObjectClass[] pointerObjectArray; }; interface TestMethodClass { From 773eeb83d8586c4175fa5455b7393e8ef56e249e Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 14 Aug 2024 20:21:24 -0300 Subject: [PATCH 057/186] Fix checking attribute method --- .../xpenatan/jparser/idl/parser/IDLAttributeParser.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java index 6daa5cd0..0d58dc67 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java @@ -190,7 +190,7 @@ public static boolean shouldSkipMethod(MethodDeclaration containsMethod) { private static MethodDeclaration containsSetMethod(ClassOrInterfaceDeclaration classOrInterfaceDeclaration, IDLAttribute idlAttribute) { String[] paramTypes = new String[1]; paramTypes[0] = idlAttribute.type; - String methodName = idlAttribute.name; + String methodName = ATTRIBUTE_PREFIX_SET + idlAttribute.name; List methods = classOrInterfaceDeclaration.getMethodsBySignature(methodName, paramTypes); if(methods.size() > 0) { @@ -201,7 +201,7 @@ private static MethodDeclaration containsSetMethod(ClassOrInterfaceDeclaration c private static MethodDeclaration containsGetMethod(ClassOrInterfaceDeclaration classOrInterfaceDeclaration, IDLAttribute idlAttribute) { String[] paramTypes = new String[0]; - String methodName = idlAttribute.name; + String methodName = ATTRIBUTE_PREFIX_GET + idlAttribute.name; List methods = classOrInterfaceDeclaration.getMethodsBySignature(methodName, paramTypes); if(methods.size() > 0) { From c34ab3d27ea3ecaa9f758cb220a6bf8dfd52f110 Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 14 Aug 2024 20:21:35 -0300 Subject: [PATCH 058/186] Add getData option --- jParser/base/src/main/resources/IDLHelper.h | 1 + 1 file changed, 1 insertion(+) diff --git a/jParser/base/src/main/resources/IDLHelper.h b/jParser/base/src/main/resources/IDLHelper.h index aa1f43b1..939818aa 100644 --- a/jParser/base/src/main/resources/IDLHelper.h +++ b/jParser/base/src/main/resources/IDLHelper.h @@ -46,6 +46,7 @@ class IDLArray { void setValue(int index, T value) { data[index] = value; } int getSize() { return size; } intptr_t getPointer() { return (intptr_t)data; } + T* getData() { return data; } }; typedef std::string IDLString; From 0a0ecf14a4d73e188f8c1f99699c821b8f9a7fa8 Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 14 Aug 2024 21:19:16 -0300 Subject: [PATCH 059/186] Fallback when method is not found --- .../com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index 09cd601c..fb3235e6 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -787,7 +787,12 @@ else if(resolvedType.isArray()) { List methodsByName = getNativeMethodsByName(classDeclaration, nativeMethodName, arguments.size(), paramT); int size = methodsByName.size(); if(size == 0) { - return null; + // The current state is not possible to get all paramT correctly. + // If method list is 0 and without passing type is 1 then use this method. + methodsByName = getNativeMethodsByName(classDeclaration, nativeMethodName, arguments.size(), null); + if(methodsByName.size() != 1) { + return null; + } } if(methodsByName.size() == 1) { MethodDeclaration methodDeclaration = methodsByName.get(0); From 41693ccf50818c4c99325f1e1ab5f987589d1f74 Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 14 Aug 2024 22:47:09 -0300 Subject: [PATCH 060/186] update test --- .../xpenatan/jparser/example/app/TestLib.java | 66 ++++++++++++++++++- .../lib/lib-build/src/main/cpp/TestLib.idl | 21 +++++- .../src/main/cpp/source/TestLib/src/TestLib.h | 32 ++++++++- 3 files changed, 112 insertions(+), 7 deletions(-) diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java index b11a089b..407fd0b3 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java @@ -1,5 +1,7 @@ package com.github.xpenatan.jparser.example.app; +import com.github.xpenatan.jparser.example.testlib.TestConstructorClass; + public class TestLib { public static boolean test() { @@ -23,8 +25,68 @@ public static boolean test() { private static boolean testConstructorClass() { - - return false; + { + int intValue01 = 40; + TestConstructorClass test = new TestConstructorClass(intValue01); + if(!(test.get_intValue01() == intValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_intValue01() == intValue01"); + } + } + { + float floatValue01 = 4.654f; + int intValue01 = 29; + TestConstructorClass test = new TestConstructorClass(floatValue01, intValue01); + + if(!(test.get_floatValue01() == floatValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_floatValue01() == floatValue01"); + } + if(!(test.get_intValue01() == intValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_intValue01() == intValue01"); + } + } + { + int intValue01 = 40; + int intValue02 = 47; + float floatValue01 = 42.5f; + float floatValue02 = 72.9f; + TestConstructorClass test = new TestConstructorClass(intValue01, intValue02, floatValue01, floatValue02); + if(!(test.get_intValue01() == intValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_intValue01() == intValue01"); + } + if(!(test.get_intValue02() == intValue02)) { + throw new RuntimeException("testConstructorClass Error: test.get_intValue02() == intValue02"); + } + if(!(test.get_floatValue01() == floatValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_floatValue01() == floatValue01"); + } + if(!(test.get_floatValue02() == floatValue02)) { + throw new RuntimeException("testConstructorClass Error: test.get_floatValue02() == floatValue02"); + } + } + { + int intValue01 = 40; + int intValue02 = 47; + float floatValue01 = 42.5f; + float floatValue02 = 72.9f; + boolean boolValue01 = true; + TestConstructorClass test = new TestConstructorClass(intValue01, intValue02, floatValue01, floatValue02, boolValue01); + if(!(test.get_intValue01() == intValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_intValue01() == intValue01"); + } + if(!(test.get_intValue02() == intValue02)) { + throw new RuntimeException("testConstructorClass Error: test.get_intValue02() == intValue02"); + } + if(!(test.get_floatValue01() == floatValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_floatValue01() == floatValue01"); + } + if(!(test.get_floatValue02() == floatValue02)) { + throw new RuntimeException("testConstructorClass Error: test.get_floatValue02() == floatValue02"); + } + if(!(test.get_boolValue01() == boolValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_boolValue01() == boolValue01"); + } + } + return true; } private static boolean testAttributeClass() { diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index c69f66ad..b9ad8710 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -5,14 +5,30 @@ interface TestObjectClass { }; interface TestConstructorClass { - [Value] attribute IDLString strValue01; + readonly attribute long intValue01; + readonly attribute long intValue02; + readonly attribute float floatValue01; + readonly attribute float floatValue02; + readonly attribute boolean boolValue01; void TestConstructorClass(long intValue01); - void TestConstructorClass(float floatValue, [Const] DOMString strValue01); + void TestConstructorClass(float floatValue, long intValue01); void TestConstructorClass(long intValue01, long intValue02, float floatValue01, float floatValue02, optional boolean boolValue01); void TestConstructorClass(long intValue01, long[] intArray, float[] floatArray); }; +interface TestStringConstructorClass { + readonly attribute long intValue01; + [Value] readonly attribute IDLString strValue01; + + // If string is not at the same order emscripten may give errors at runtime + // VM41:980 Invalid UTF-8 leading byte 0x000000fe encountered when deserializing a UTF-8 string in wasm memory to a JS string! + + void TestStringConstructorClass([Const] DOMString strValue01); + void TestStringConstructorClass([Const] DOMString strValue01, long intValue01); + void TestStringConstructorClass([Const] DOMString strValue01, float floatValue01, long intValue01); +}; + interface TestAttributeClass { void TestAttributeClass(); readonly attribute long readOnlyIntValue01; @@ -48,6 +64,7 @@ interface TestAttributeArrayClass { interface TestMethodClass { void TestMethodClass(); + void TestMethodClass([Const] DOMString strValue01); void setMethod01(long intValue01); void setMethod02(float floatValue01, boolean boolValue01); void setMethod03(long intValue01, long intValue02, float floatValue01, float floatValue02, optional boolean boolValue01); diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h index 5b259fab..ad16c3a1 100644 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h @@ -71,14 +71,13 @@ class TestConstructorClass { float floatValue01; float floatValue02; bool boolValue01; - string strValue01; TestConstructorClass(int intValue01) { this->intValue01 = intValue01; }; - TestConstructorClass(float floatValue01, const char* strValue01) { + TestConstructorClass(float floatValue01, int intValue01) { this->floatValue01 = floatValue01; - this->strValue01 = strValue01; + this->intValue01 = intValue01; }; TestConstructorClass(int intValue01, int intValue02, float floatValue01, float floatValue02, bool boolValue01 = true) { this->intValue01 = intValue01; @@ -96,6 +95,28 @@ class TestConstructorClass { }; }; +class TestStringConstructorClass { + private: + + public: + int intValue01; + int floatValue01; + string strValue01; + + TestStringConstructorClass(const char* strValue01) { + this->strValue01 = strValue01; + }; + TestStringConstructorClass(const char* strValue01, int intValue01) { + this->strValue01 = strValue01; + this->intValue01 = intValue01; + }; + TestStringConstructorClass(const char* strValue01, float floatValue01, int intValue01) { + this->strValue01 = strValue01; + this->floatValue01 = floatValue01; + this->intValue01 = intValue01; + }; +}; + class TestMethodClass { private: int intValue01; @@ -113,6 +134,10 @@ class TestMethodClass { pointerObject01 = NULL; pointerObject02 = NULL; }; + TestMethodClass(const char* strValue01) { + cout << "strValue01 before: " << strValue01 << endl; + this->strValue01 = strValue01; + }; void setMethod01(int intValue01) { this->intValue01 = intValue01; }; @@ -135,6 +160,7 @@ class TestMethodClass { floatArraySize2[1] = 4.2; }; void setMethod05(const char* strValue01) { + cout << "strValue01 before: " << strValue01 << endl; this->strValue01 = strValue01; }; void setMethod06(const TestObjectClass* pointerObject01, TestObjectClass* pointerObject02, const TestObjectClass& refObject01, TestObjectClass& refObject02) { From 9a4e89b6dcd43ca3fcfd29b926e9f9345833e898 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 15 Aug 2024 08:26:06 -0300 Subject: [PATCH 061/186] Update comments --- example/lib/lib-build/src/main/cpp/TestLib.idl | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index b9ad8710..6caded14 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -1,3 +1,13 @@ +// NOTE: +// * Emscripten webidl does not support [Value] object passed by parameter. Better to pass it as [Ref] +// * [BUG] Emscripten may give runtime errors if string is not at the same order in a overloading method or constructor parameter. +// See: TestStringConstructorClass. +// Error: VM41:980 Invalid UTF-8 leading byte 0x000000fe encountered when deserializing a UTF-8 string in wasm memory to a JS string! +// * Emscripten WebIDL does not support overloading method/constructor with different types at the same parameter size. +// Ex: void myMethod(float param1, boolean param2) and void myMethod(boolean param1, float param2) will not compile. +// It needs to be at the same order if both have the same parameter size. +// TestConstructorClass works because it have different parameter size. From the [BUG] above, don't use string or it will fail at runtime. + interface TestObjectClass { void TestObjectClass(); attribute long intValue01; @@ -21,9 +31,6 @@ interface TestStringConstructorClass { readonly attribute long intValue01; [Value] readonly attribute IDLString strValue01; - // If string is not at the same order emscripten may give errors at runtime - // VM41:980 Invalid UTF-8 leading byte 0x000000fe encountered when deserializing a UTF-8 string in wasm memory to a JS string! - void TestStringConstructorClass([Const] DOMString strValue01); void TestStringConstructorClass([Const] DOMString strValue01, long intValue01); void TestStringConstructorClass([Const] DOMString strValue01, float floatValue01, long intValue01); From 3e66cdf3d7ff2bd903555bbdb72c0f148e7d62fa Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 15 Aug 2024 09:21:51 -0300 Subject: [PATCH 062/186] Make all native calls public and starts with native_ --- .../github/xpenatan/jparser/idl/parser/IDLMethodParser.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java index 10c69858..310f5dbf 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java @@ -36,6 +36,8 @@ public class IDLMethodParser { + static final String NATIVE_METHOD = "native_"; + static final String GET_OBJECT_TEMPLATE = "{\n" + " long pointer = [METHOD];\n" + @@ -346,8 +348,8 @@ public static MethodDeclaration generateNativeMethod(boolean isReturnValue, Stri // Clone some generated idl method settings MethodDeclaration nativeMethod = new MethodDeclaration(); - nativeMethod.setName(methodName + "NATIVE"); - nativeMethod.setModifiers(Modifier.createModifierList(Modifier.Keyword.PRIVATE, Modifier.Keyword.STATIC, Modifier.Keyword.NATIVE)); + nativeMethod.setName(NATIVE_METHOD + methodName); + nativeMethod.setModifiers(Modifier.createModifierList(Modifier.Keyword.PUBLIC, Modifier.Keyword.STATIC, Modifier.Keyword.NATIVE)); nativeMethod.removeBody(); if(!isStatic) { From a4fdf7bed42dfc7e910f78d43bf5ee66871320d6 Mon Sep 17 00:00:00 2001 From: Natan Date: Fri, 16 Aug 2024 08:47:18 -0300 Subject: [PATCH 063/186] add _ suffix in static library. Add vc to test --- .../lib/lib-build/src/main/java/BuildLib.java | 37 ++++++++++++++++--- .../builder/targets/EmscriptenTarget.java | 2 +- .../jparser/builder/targets/IOSTarget.java | 2 +- .../jparser/builder/targets/LinuxTarget.java | 2 +- .../jparser/builder/targets/MacTarget.java | 2 +- ...MSVSTarget.java => WindowsMSVCTarget.java} | 7 ++-- .../builder/targets/WindowsTarget.java | 2 +- 7 files changed, 40 insertions(+), 14 deletions(-) rename jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/{WindowsMSVSTarget.java => WindowsMSVCTarget.java} (86%) diff --git a/example/lib/lib-build/src/main/java/BuildLib.java b/example/lib/lib-build/src/main/java/BuildLib.java index 4263bfbd..11d11036 100644 --- a/example/lib/lib-build/src/main/java/BuildLib.java +++ b/example/lib/lib-build/src/main/java/BuildLib.java @@ -4,6 +4,7 @@ import com.github.xpenatan.jparser.builder.targets.IOSTarget; import com.github.xpenatan.jparser.builder.targets.LinuxTarget; import com.github.xpenatan.jparser.builder.targets.MacTarget; +import com.github.xpenatan.jparser.builder.targets.WindowsMSVCTarget; import com.github.xpenatan.jparser.builder.targets.WindowsTarget; import com.github.xpenatan.jparser.builder.tool.BuildToolListener; import com.github.xpenatan.jparser.builder.tool.BuildToolOptions; @@ -27,6 +28,7 @@ public void onAddTarget(BuildToolOptions op, IDLReader idlReader, ArrayList Date: Fri, 16 Aug 2024 10:05:07 -0300 Subject: [PATCH 064/186] Add msvc debug option --- .../jparser/builder/targets/WindowsMSVCTarget.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java index 32a7ad10..840f193a 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java @@ -5,6 +5,10 @@ public class WindowsMSVCTarget extends DefaultBuildTarget { + public static boolean DEBUG_BUILD; + + // https://learn.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-by-category?view=msvc-170 + public WindowsMSVCTarget() { this.libDirSuffix = "windows/vc/"; this.tempBuildDir = "target/windows"; @@ -21,6 +25,13 @@ public WindowsMSVCTarget() { compilerOutputCommand = "-Fo:"; cppFlags.add("-std:c++17"); cppFlags.add("-c"); + if(DEBUG_BUILD) { + cppFlags.add("/Z7"); // add debug information in .obj to work in visual studio + cppFlags.add("/Od"); + } + else { + cppFlags.add("/O2"); + } linkerOutputCommand = "/OUT:"; libSuffix = "64.dll"; } @@ -35,6 +46,9 @@ protected void setup(BuildConfig config) { } else { linkerCompiler.add("link"); + if(DEBUG_BUILD) { + linkerCompiler.add("/DEBUG"); // Generates .pbd file + } linkerFlags.add("-DLL"); } linkerCompiler.add("/NOLOGO"); From 77060196d380e438b0caf7b4ab7ab5ef4591ca46 Mon Sep 17 00:00:00 2001 From: Natan Date: Fri, 16 Aug 2024 10:05:32 -0300 Subject: [PATCH 065/186] Change demo to use msvc --- example/lib/lib-desktop/build.gradle.kts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/example/lib/lib-desktop/build.gradle.kts b/example/lib/lib-desktop/build.gradle.kts index 6342fd98..f26010e4 100644 --- a/example/lib/lib-desktop/build.gradle.kts +++ b/example/lib/lib-desktop/build.gradle.kts @@ -3,7 +3,8 @@ plugins { } val libDir = "${projectDir}/../lib-build/build/c++/libs" -val windowsFile = "$libDir/windows/TestLib64.dll" +//val windowsFile = "$libDir/windows/TestLib64.dll" +val windowsFile = "$libDir/windows/vc/TestLib64.dll" val linuxFile = "$libDir/linux/libTestLib64.so" val macFile = "$libDir/mac/libTestLib64.dylib" val macArmFile = "$libDir/mac/arm/libTestLibarm64.dylib" From 97fdc9b5c73008c37d033567956aab446003f3a1 Mon Sep 17 00:00:00 2001 From: Natan Date: Fri, 16 Aug 2024 10:13:15 -0300 Subject: [PATCH 066/186] Remove linux from windows flag --- .../github/xpenatan/jparser/builder/tool/BuildToolOptions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jParser/builder-tool/src/main/java/com/github/xpenatan/jparser/builder/tool/BuildToolOptions.java b/jParser/builder-tool/src/main/java/com/github/xpenatan/jparser/builder/tool/BuildToolOptions.java index 89230d7d..c7a3abd2 100644 --- a/jParser/builder-tool/src/main/java/com/github/xpenatan/jparser/builder/tool/BuildToolOptions.java +++ b/jParser/builder-tool/src/main/java/com/github/xpenatan/jparser/builder/tool/BuildToolOptions.java @@ -63,7 +63,7 @@ public BuildToolOptions(String libName, String libBasePackage, String modulePref boolean teavmtmp = false; for(int i = 0; i < platform.length; i++) { String arg = platform[i]; - if(arg.equals("windows64") && (BuildTarget.isWindows() || BuildTarget.isUnix())) { + if(arg.equals("windows64") && (BuildTarget.isWindows())) { windows64tmp = true; } else if(arg.equals("linux64") && BuildTarget.isUnix()) { From 23de31d7bad58ac4decd16e2377f980ed7b2e7c9 Mon Sep 17 00:00:00 2001 From: Natan Date: Fri, 16 Aug 2024 10:19:52 -0300 Subject: [PATCH 067/186] ignore crash logs --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0e47b640..4eaf89b7 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ local.properties out/ *.ini .temp/ +*.log **/webapp/** **/lib/core/src/** From 6148be6df01abfc91dd7d57a79abd70b20e550ab Mon Sep 17 00:00:00 2001 From: Natan Date: Fri, 16 Aug 2024 23:55:20 -0300 Subject: [PATCH 068/186] add new solution to public native calls --- .gitignore | 4 +- .../xpenatan/jparser/example/app/TestLib.java | 183 ++++++++++++++---- .../lib/lib-build/src/main/cpp/TestLib.idl | 14 ++ .../src/main/cpp/custom/CustomCode.h | 18 +- .../src/main/cpp/source/TestLib/src/TestLib.h | 15 +- .../lib/lib-build/src/main/java/BuildLib.java | 5 + example/lib/lib-teavm/build.gradle.kts | 14 +- .../src/main/java/idl/helper/IDLString.java | 8 +- .../main/java/idl/helper/IDLStringView.java | 4 +- jParser/base/src/main/resources/IDLHelper.h | 2 +- jParser/base/src/main/resources/IDLHelper.idl | 10 +- .../github/xpenatan/jparser/core/JParser.java | 2 - .../idl/parser/IDLClassGeneratorParser.java | 162 +++++++++++++++- .../idl/parser/IDLDeConstructorParser.java | 2 +- .../jparser/idl/parser/IDLMethodParser.java | 23 +-- .../jparser/teavm/TeaVMCodeParser.java | 20 +- 16 files changed, 377 insertions(+), 109 deletions(-) diff --git a/.gitignore b/.gitignore index 4eaf89b7..5c487971 100644 --- a/.gitignore +++ b/.gitignore @@ -32,8 +32,6 @@ out/ **/webapp/** **/lib/core/src/** **/lib/desktop/src/main/** -**/lib-ext/ext-core/src/** -**/lib-ext/ext-desktop/src/main/** -**/lib/lib-teavm/src/main/java/emu/** +**/lib/lib-teavm/src/main/java/** **/lib/lib-core/src/main/java/** **/app/android/libs/ diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java index 407fd0b3..c554c8e4 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java @@ -1,11 +1,15 @@ package com.github.xpenatan.jparser.example.app; import com.github.xpenatan.jparser.example.testlib.TestConstructorClass; +import com.github.xpenatan.jparser.example.testlib.TestMethodClass; +import com.github.xpenatan.jparser.example.testlib.TestObjectClass; +import com.github.xpenatan.jparser.example.testlib.TestObjectClassArray; public class TestLib { public static boolean test() { boolean constructorTest = testConstructorClass(); + boolean stringConstructorTest = testStringConstructorClass(); boolean attributeTest = testAttributeClass(); boolean staticAttributeTest = testStaticAttributeClass(); boolean attributeArrayTest = testAttributeArrayClass(); @@ -14,35 +18,49 @@ public static boolean test() { boolean callbackTest = testCallbackClass(); System.out.println("constructorTest: " + constructorTest); + System.out.println("stringConstructorTest: " + stringConstructorTest); System.out.println("attributeTest: " + attributeTest); System.out.println("staticAttributeTest: " + staticAttributeTest); System.out.println("attributeArrayTest: " + attributeArrayTest); System.out.println("methodTest: " + methodTest); System.out.println("staticMethodTest: " + staticMethodTest); System.out.println("callbackTest: " + callbackTest); - return attributeTest && attributeArrayTest; + return constructorTest && stringConstructorTest && attributeTest && staticAttributeTest + && attributeArrayTest && methodTest && staticMethodTest && callbackTest; } private static boolean testConstructorClass() { - { int intValue01 = 40; TestConstructorClass test = new TestConstructorClass(intValue01); - if(!(test.get_intValue01() == intValue01)) { - throw new RuntimeException("testConstructorClass Error: test.get_intValue01() == intValue01"); + try { + if(!(test.get_intValue01() == intValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_intValue01() == intValue01"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; } + test.dispose(); } { float floatValue01 = 4.654f; int intValue01 = 29; TestConstructorClass test = new TestConstructorClass(floatValue01, intValue01); - - if(!(test.get_floatValue01() == floatValue01)) { - throw new RuntimeException("testConstructorClass Error: test.get_floatValue01() == floatValue01"); - } - if(!(test.get_intValue01() == intValue01)) { - throw new RuntimeException("testConstructorClass Error: test.get_intValue01() == intValue01"); + try { + if(!(test.get_floatValue01() == floatValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_floatValue01() == floatValue01"); + } + if(!(test.get_intValue01() == intValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_intValue01() == intValue01"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; } + test.dispose(); } { int intValue01 = 40; @@ -50,18 +68,25 @@ private static boolean testConstructorClass() { float floatValue01 = 42.5f; float floatValue02 = 72.9f; TestConstructorClass test = new TestConstructorClass(intValue01, intValue02, floatValue01, floatValue02); - if(!(test.get_intValue01() == intValue01)) { - throw new RuntimeException("testConstructorClass Error: test.get_intValue01() == intValue01"); - } - if(!(test.get_intValue02() == intValue02)) { - throw new RuntimeException("testConstructorClass Error: test.get_intValue02() == intValue02"); - } - if(!(test.get_floatValue01() == floatValue01)) { - throw new RuntimeException("testConstructorClass Error: test.get_floatValue01() == floatValue01"); - } - if(!(test.get_floatValue02() == floatValue02)) { - throw new RuntimeException("testConstructorClass Error: test.get_floatValue02() == floatValue02"); + try { + if(!(test.get_intValue01() == intValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_intValue01() == intValue01"); + } + if(!(test.get_intValue02() == intValue02)) { + throw new RuntimeException("testConstructorClass Error: test.get_intValue02() == intValue02"); + } + if(!(test.get_floatValue01() == floatValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_floatValue01() == floatValue01"); + } + if(!(test.get_floatValue02() == floatValue02)) { + throw new RuntimeException("testConstructorClass Error: test.get_floatValue02() == floatValue02"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; } + test.dispose(); } { int intValue01 = 40; @@ -70,58 +95,130 @@ private static boolean testConstructorClass() { float floatValue02 = 72.9f; boolean boolValue01 = true; TestConstructorClass test = new TestConstructorClass(intValue01, intValue02, floatValue01, floatValue02, boolValue01); - if(!(test.get_intValue01() == intValue01)) { - throw new RuntimeException("testConstructorClass Error: test.get_intValue01() == intValue01"); - } - if(!(test.get_intValue02() == intValue02)) { - throw new RuntimeException("testConstructorClass Error: test.get_intValue02() == intValue02"); - } - if(!(test.get_floatValue01() == floatValue01)) { - throw new RuntimeException("testConstructorClass Error: test.get_floatValue01() == floatValue01"); - } - if(!(test.get_floatValue02() == floatValue02)) { - throw new RuntimeException("testConstructorClass Error: test.get_floatValue02() == floatValue02"); - } - if(!(test.get_boolValue01() == boolValue01)) { - throw new RuntimeException("testConstructorClass Error: test.get_boolValue01() == boolValue01"); + try { + if(!(test.get_intValue01() == intValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_intValue01() == intValue01"); + } + if(!(test.get_intValue02() == intValue02)) { + throw new RuntimeException("testConstructorClass Error: test.get_intValue02() == intValue02"); + } + if(!(test.get_floatValue01() == floatValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_floatValue01() == floatValue01"); + } + if(!(test.get_floatValue02() == floatValue02)) { + throw new RuntimeException("testConstructorClass Error: test.get_floatValue02() == floatValue02"); + } + if(!(test.get_boolValue01() == boolValue01)) { + throw new RuntimeException("testConstructorClass Error: test.get_boolValue01() == boolValue01"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; } + test.dispose(); } return true; } + private static boolean testStringConstructorClass() { + + return true; + } + private static boolean testAttributeClass() { - return false; + return true; } private static boolean testStaticAttributeClass() { - return false; + return true; } private static boolean testAttributeArrayClass() { - return false; + return true; } private static boolean testMethodClass() { - - - return false; + { + TestMethodClass test = new TestMethodClass(); + test.setMethod01(10); + int intValue01 = test.getIntValue01(); + try { + if(!(intValue01 == 10)) { + test.dispose(); + throw new RuntimeException("intValue01 == 10"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } + { + TestMethodClass test = new TestMethodClass(); + TestObjectClassArray array = new TestObjectClassArray(2); + TestObjectClass obj1 = new TestObjectClass(); + TestObjectClass obj2 = new TestObjectClass(); + obj1.set_floatValue01(20.5f); + obj1.set_intValue01(30); + obj2.set_floatValue01(40.5f); + obj2.set_intValue01(60); + array.setValue(0, obj1); + array.setValue(1, obj2); + try { + TestMethodClass.native_setMethod07(test.getCPointer(), array.getPointer()); + { + float intValue01 = obj1.get_intValue01(); + if(!(intValue01 == 20)) { + throw new RuntimeException("intValue01 == 20"); + } + float floatValue01 = obj1.get_floatValue01(); + if(!(floatValue01 == 10.4f)) { + throw new RuntimeException("floatValue01 == 10.4f"); + } + } + { + float intValue01 = obj2.get_intValue01(); + if(!(intValue01 == 40)) { + throw new RuntimeException("intValue01 == 40"); + } + float floatValue01 = obj2.get_floatValue01(); + if(!(floatValue01 == 30.8f)) { + throw new RuntimeException("floatValue01 == 30.8f"); + } + } + } catch(Throwable e) { + e.printStackTrace(); + obj1.dispose(); + obj2.dispose(); + array.dispose(); + test.dispose(); + return false; + } + obj1.dispose(); + obj2.dispose(); + array.dispose(); + test.dispose(); + } + return true; } private static boolean testStaticMethodClass() { - return false; + return true; } private static boolean testCallbackClass() { - return false; + return true; } } \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index 6caded14..e3bc8939 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -7,6 +7,9 @@ // Ex: void myMethod(float param1, boolean param2) and void myMethod(boolean param1, float param2) will not compile. // It needs to be at the same order if both have the same parameter size. // TestConstructorClass works because it have different parameter size. From the [BUG] above, don't use string or it will fail at runtime. +// * Arrays parameters for example "void method(int[] array)" is converted to IDLIntArray class object behind the scene because interacting with array is better using native code. +// For custom types is better to use typedef. See TestObjectClassArray in CustomCode.h + interface TestObjectClass { void TestObjectClass(); @@ -14,6 +17,16 @@ interface TestObjectClass { attribute float floatValue01; }; +interface TestObjectClassArray { + void TestObjectClassArray(long size); + void resize(long size); + void clear(); + TestObjectClass getValue(long index); + void setValue(long index, TestObjectClass value); + long getSize(); + any getPointer(); +}; + interface TestConstructorClass { readonly attribute long intValue01; readonly attribute long intValue02; @@ -78,6 +91,7 @@ interface TestMethodClass { void setMethod04(long intValue01, long[] intArray, float[] floatArray); void setMethod05([Const] DOMString strValue01); void setMethod06([Const] TestObjectClass pointerObject01, TestObjectClass pointerObject02, [Const, Ref] TestObjectClass refObject01, [Ref] TestObjectClass refObject02); + void setMethod07(TestObjectClass pointerObjectArray); long getIntValue01(); long getIntValue02(); diff --git a/example/lib/lib-build/src/main/cpp/custom/CustomCode.h b/example/lib/lib-build/src/main/cpp/custom/CustomCode.h index 17f0a084..3957cace 100644 --- a/example/lib/lib-build/src/main/cpp/custom/CustomCode.h +++ b/example/lib/lib-build/src/main/cpp/custom/CustomCode.h @@ -1,18 +1,8 @@ -#include "ReturnClass.h" -#include "ParentClass.h" -#include "OperatorClass.h" -#include "NormalClass.h" -#include "InterfaceClass.h" -#include "DefaultInterface.h" -#include "subpackage/ParamData.h" -#include "DefaultParamsClass.h" +#include "IDLHelper.h" #include "TestLib.h" -typedef NormalClass::EnumWithinClass EnumWithinClass; -typedef NormalClass::EnumClassWithinClass EnumClassWithinClass; -typedef EnumNamespace::EnumInNamespace EnumInNamespace; - - typedef TestEnumClass::TestEnumWithinClass TestEnumWithinClass; typedef TestEnumClass::TestEnumClassWithinClass TestEnumClassWithinClass; -typedef TestEnumNamespace::TestEnumInNamespace TestEnumInNamespace; \ No newline at end of file +typedef TestEnumNamespace::TestEnumInNamespace TestEnumInNamespace; + +typedef IDLArray TestObjectClassArray; \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h index ad16c3a1..72ba95fc 100644 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h @@ -127,6 +127,7 @@ class TestMethodClass { string strValue01; const TestObjectClass* pointerObject01; TestObjectClass* pointerObject02; + TestObjectClass** pointerObjectArray; TestObjectClass refObject01; TestObjectClass refObject02; public: @@ -160,7 +161,6 @@ class TestMethodClass { floatArraySize2[1] = 4.2; }; void setMethod05(const char* strValue01) { - cout << "strValue01 before: " << strValue01 << endl; this->strValue01 = strValue01; }; void setMethod06(const TestObjectClass* pointerObject01, TestObjectClass* pointerObject02, const TestObjectClass& refObject01, TestObjectClass& refObject02) { @@ -169,6 +169,18 @@ class TestMethodClass { this->refObject01 = refObject01; this->refObject02 = refObject02; }; + void setMethod07(TestObjectClass* pointerObjectArray) { + this->pointerObjectArray = ((TestObjectClass** )pointerObjectArray); +// this->pointerObjectArray = &pointerObjectArray[0]; +// this->pointerObjectArray = &(*array[0]); + + TestObjectClass* obj1 = this->pointerObjectArray[0]; + TestObjectClass* obj2 = this->pointerObjectArray[1]; + obj1->intValue01 = 20; + obj1->floatValue01 = 10.4; + obj2->intValue01 = 40; + obj2->floatValue01 = 30.8; + }; int getIntValue01() { return intValue01; }; int getIntValue02() { return intValue02; }; @@ -309,7 +321,6 @@ class TestCallbackClass { class TestEnumClass { private: - ParamData data; public: enum TestEnumWithinClass { diff --git a/example/lib/lib-build/src/main/java/BuildLib.java b/example/lib/lib-build/src/main/java/BuildLib.java index 11d11036..ddd27e02 100644 --- a/example/lib/lib-build/src/main/java/BuildLib.java +++ b/example/lib/lib-build/src/main/java/BuildLib.java @@ -9,6 +9,7 @@ import com.github.xpenatan.jparser.builder.tool.BuildToolListener; import com.github.xpenatan.jparser.builder.tool.BuildToolOptions; import com.github.xpenatan.jparser.builder.tool.BuilderTool; +import com.github.xpenatan.jparser.cpp.NativeCPPGenerator; import com.github.xpenatan.jparser.idl.IDLReader; import java.util.ArrayList; @@ -19,6 +20,10 @@ public static void main(String[] args) throws Exception { String modulePrefix = "lib"; String basePackage = "com.github.xpenatan.jparser.example.testlib"; String sourceDir = "/src/main/cpp/source/TestLib/src"; + + WindowsMSVCTarget.DEBUG_BUILD = true; +// NativeCPPGenerator.SKIP_GLUE_CODE = true; + BuildToolOptions op = new BuildToolOptions(libName, basePackage, modulePrefix, sourceDir, args); BuilderTool.build(op, new BuildToolListener() { @Override diff --git a/example/lib/lib-teavm/build.gradle.kts b/example/lib/lib-teavm/build.gradle.kts index 9abedb40..1a527f03 100644 --- a/example/lib/lib-teavm/build.gradle.kts +++ b/example/lib/lib-teavm/build.gradle.kts @@ -21,17 +21,17 @@ dependencies { else { implementation(project(":jParser:loader:loader-core")) } - testImplementation(project(":example:lib:lib-core")) - testImplementation("junit:junit:${LibExt.jUnitVersion}") - testImplementation("org.teavm:teavm-core:${LibExt.teaVMVersion}") - testImplementation("org.teavm:teavm-jso-apis:${LibExt.teaVMVersion}") - testImplementation("org.teavm:teavm-classlib:${LibExt.teaVMVersion}") - testImplementation("org.teavm:teavm-junit:${LibExt.teaVMVersion}") +// testImplementation(project(":example:lib:lib-core")) +// testImplementation("junit:junit:${LibExt.jUnitVersion}") +// testImplementation("org.teavm:teavm-core:${LibExt.teaVMVersion}") +// testImplementation("org.teavm:teavm-jso-apis:${LibExt.teaVMVersion}") +// testImplementation("org.teavm:teavm-classlib:${LibExt.teaVMVersion}") +// testImplementation("org.teavm:teavm-junit:${LibExt.teaVMVersion}") } tasks.named("clean") { doFirst { - val srcPath = "$projectDir/src/main/java/gen" + val srcPath = "$projectDir/src/main/java" project.delete(files(srcPath)) } } diff --git a/jParser/base/src/main/java/idl/helper/IDLString.java b/jParser/base/src/main/java/idl/helper/IDLString.java index e8bc0f51..3fbd068a 100644 --- a/jParser/base/src/main/java/idl/helper/IDLString.java +++ b/jParser/base/src/main/java/idl/helper/IDLString.java @@ -20,7 +20,7 @@ public IDLString() { public IDLString(byte b, char c) {} public String c_str() { - String text = c_strNATIVE(getCPointer()); + String text = internal_native_c_str(getCPointer()); return text; } @@ -35,10 +35,10 @@ public String c_str() { var returnedJSObj = jsObj.c_str(); return returnedJSObj; */ - private static native String c_strNATIVE(long this_addr); + private static native String internal_native_c_str(long this_addr); public String data() { - String text = dataNATIVE(getCPointer()); + String text = internal_native_data(getCPointer()); return text; } @@ -53,5 +53,5 @@ public String data() { var returnedJSObj = jsObj.data(); return returnedJSObj; */ - private static native String dataNATIVE(long this_addr); + private static native String internal_native_data(long this_addr); } \ No newline at end of file diff --git a/jParser/base/src/main/java/idl/helper/IDLStringView.java b/jParser/base/src/main/java/idl/helper/IDLStringView.java index 66144a96..5f5b7721 100644 --- a/jParser/base/src/main/java/idl/helper/IDLStringView.java +++ b/jParser/base/src/main/java/idl/helper/IDLStringView.java @@ -20,7 +20,7 @@ public IDLStringView() { public IDLStringView(byte b, char c) {} public String data() { - String text = dataNATIVE(getCPointer()); + String text = internal_native_data(getCPointer()); return text; } @@ -35,5 +35,5 @@ public String data() { var returnedJSObj = jsObj.data(); return returnedJSObj; */ - private static native String dataNATIVE(long this_addr); + private static native String internal_native_data(long this_addr); } \ No newline at end of file diff --git a/jParser/base/src/main/resources/IDLHelper.h b/jParser/base/src/main/resources/IDLHelper.h index 939818aa..3aea32a3 100644 --- a/jParser/base/src/main/resources/IDLHelper.h +++ b/jParser/base/src/main/resources/IDLHelper.h @@ -45,7 +45,7 @@ class IDLArray { T getValue(int index) { return data[index]; } void setValue(int index, T value) { data[index] = value; } int getSize() { return size; } - intptr_t getPointer() { return (intptr_t)data; } + void* getPointer() { return (void*)data; } T* getData() { return data; } }; diff --git a/jParser/base/src/main/resources/IDLHelper.idl b/jParser/base/src/main/resources/IDLHelper.idl index a0676faf..73db12f7 100644 --- a/jParser/base/src/main/resources/IDLHelper.idl +++ b/jParser/base/src/main/resources/IDLHelper.idl @@ -25,7 +25,7 @@ interface IDLBoolArray { boolean getValue(long index); void setValue(long index, boolean value); long getSize(); - long getPointer(); + any getPointer(); void copy([Ref] IDLBoolArray src, long srcOffset, long destOffset, long length); }; @@ -36,7 +36,7 @@ interface IDLIntArray { long getValue(long index); void setValue(long index, long value); long getSize(); - long getPointer(); + any getPointer(); void copy([Ref] IDLIntArray src, long srcOffset, long destOffset, long length); }; @@ -47,7 +47,7 @@ interface IDLFloatArray { float getValue(long index); void setValue(long index, float value); long getSize(); - long getPointer(); + any getPointer(); void copy([Ref] IDLFloatArray src, long srcOffset, long destOffset, long length); }; @@ -58,7 +58,7 @@ interface IDLDoubleArray { double getValue(long index); void setValue(long index, double value); long getSize(); - long getPointer(); + any getPointer(); void copy([Ref] IDLDoubleArray src, long srcOffset, long destOffset, long length); }; @@ -69,6 +69,6 @@ interface IDLByteArray { byte getValue(long index); void setValue(long index, byte value); long getSize(); - long getPointer(); + any getPointer(); void copy([Ref] IDLByteArray src, long srcOffset, long destOffset, long length); }; \ No newline at end of file diff --git a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParser.java b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParser.java index bfe071b4..1d8773c8 100644 --- a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParser.java +++ b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParser.java @@ -1,13 +1,11 @@ package com.github.xpenatan.jparser.core; -import com.github.javaparser.ParserConfiguration; import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.PackageDeclaration; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.comments.BlockComment; -import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.symbolsolver.JavaSymbolSolver; import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver; import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java index 58166756..996a05f0 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java @@ -4,14 +4,23 @@ import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.ImportDeclaration; import com.github.javaparser.ast.Modifier; +import com.github.javaparser.ast.Node; import com.github.javaparser.ast.NodeList; +import com.github.javaparser.ast.body.BodyDeclaration; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.ConstructorDeclaration; import com.github.javaparser.ast.body.FieldDeclaration; +import com.github.javaparser.ast.body.InitializerDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.Parameter; +import com.github.javaparser.ast.expr.MethodCallExpr; import com.github.javaparser.ast.expr.Name; import com.github.javaparser.ast.type.ClassOrInterfaceType; +import com.github.javaparser.ast.type.PrimitiveType; import com.github.javaparser.ast.type.Type; +import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; +import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserMethodDeclaration; +import com.github.javaparser.utils.Pair; import com.github.xpenatan.jparser.core.JParser; import com.github.xpenatan.jparser.core.JParserHelper; import com.github.xpenatan.jparser.core.JParserItem; @@ -33,6 +42,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; +import java.util.Optional; import java.util.regex.Pattern; /** @@ -56,11 +66,10 @@ public abstract class IDLClassGeneratorParser extends DefaultCodeParser { protected String includeDir; /** - * * @param basePackage Base module source. This is used to generate other sources - * @param headerCMD This is the first command option that this parser will use. Ex teavm, C++. - * @param idlReader Contains the parsed idl files - * @param includeDir This is used to add java subpackages from c++ tree. Without this all java source will be at the root package. + * @param headerCMD This is the first command option that this parser will use. Ex teavm, C++. + * @param idlReader Contains the parsed idl files + * @param includeDir This is used to add java subpackages from c++ tree. Without this all java source will be at the root package. */ public IDLClassGeneratorParser(String basePackage, String headerCMD, IDLReader idlReader, String includeDir) { super(headerCMD); @@ -68,7 +77,8 @@ public IDLClassGeneratorParser(String basePackage, String headerCMD, IDLReader i this.basePackage = basePackage; this.idlReader = idlReader; if(this.includeDir != null) { - this.includeDir = this.includeDir.replace("\\", "/").replace("//", "/");; + this.includeDir = this.includeDir.replace("\\", "/").replace("//", "/"); + ; } } @@ -330,8 +340,150 @@ public void onParserComplete(JParser jParser, ArrayList parserItems } } } + + // Add additional method to call natives + + for(int i = 0; i < parserItems.size(); i++) { + JParserItem parserItem = parserItems.get(i); + String className = parserItem.className; + CompilationUnit unit = parserItem.unit; + List classDeclarations = unit.findAll(ClassOrInterfaceDeclaration.class); + + for(int i1 = 0; i1 < classDeclarations.size(); i1++) { + ClassOrInterfaceDeclaration classDeclaration = classDeclarations.get(i1); + + ArrayList> pairList = new ArrayList<>(); + + List methodCalls = classDeclaration.findAll(MethodCallExpr.class); + + for(int i2 = 0; i2 < methodCalls.size(); i2++) { + MethodCallExpr methodCallExpr = methodCalls.get(i2); + + try { + ResolvedMethodDeclaration resolve = methodCallExpr.resolve(); + if(resolve instanceof JavaParserMethodDeclaration) { + JavaParserMethodDeclaration jpmd = (JavaParserMethodDeclaration)resolve; + MethodDeclaration nativeMethod = jpmd.getWrappedNode(); + if(nativeMethod.isNative()) { + Node node = methodCallExpr.getParentNode().get(); + while(node != null) { + if(node instanceof MethodDeclaration) { + MethodDeclaration callMethod = (MethodDeclaration)node; + pairList.add(new Pair<>(callMethod, nativeMethod)); + break; + } + else if(node instanceof ConstructorDeclaration) { + pairList.add(new Pair<>(null, nativeMethod)); + break; + } + Optional parentNode = node.getParentNode(); + node = parentNode.orElse(null); + } + } + } + } catch(Throwable t) { + } + } + + for(int i2 = 0; i2 < pairList.size(); i2++) { + Pair pair = pairList.get(i2); + MethodDeclaration methodDeclaration = pair.a; + MethodDeclaration nativeMethod = pair.b; + duplicateNativeMethodToLong(classDeclaration, methodDeclaration, nativeMethod); + } + } + } } + private void duplicateNativeMethodToLong(ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, MethodDeclaration nativeMethod) { + // Because all native code convert int to long. If it's called from outside the library teavm will give errors. + // This is to duplicate all native code method to keep the long address parameters. + + MethodDeclaration clone = nativeMethod.clone(); + clone.getAnnotations().clear(); + clone.removeModifier(Modifier.Keyword.NATIVE); + clone.removeModifier(Modifier.Keyword.PRIVATE); + clone.removeModifier(Modifier.Keyword.STATIC); + clone.addModifier(Modifier.Keyword.PUBLIC); + clone.addModifier(Modifier.Keyword.STATIC); + clone.removeComment(); + NodeList parameters = clone.getParameters(); + int paramSize = parameters.size(); + for(int i1 = 0; i1 < paramSize; i1++) { + Parameter parameter = parameters.get(i1); + String paramName = parameter.getNameAsString(); + if(paramName.endsWith("_addr")) { + parameter.setType(PrimitiveType.longType()); + } + } + if(!clone.getNameAsString().contains(IDLMethodParser.NATIVE_METHOD)) { + return; + } + String newName = clone.getNameAsString().replace(IDLMethodParser.NATIVE_METHOD, "native_"); + clone.setName(newName); + + String returnStr = "\t"; + + if(methodDeclaration == null) { + // Is constructor + Type type = nativeMethod.getType(); + if(JParserHelper.isLong(type)) { + returnStr += "return "; + clone.setType(PrimitiveType.longType()); + } + } + else { + Type type = methodDeclaration.getType(); + if(type.isClassOrInterfaceType() && !nativeMethod.isClassOrInterfaceDeclaration()) { + returnStr += "return "; + clone.setType(PrimitiveType.longType()); + } + else if(!type.isVoidType()) { + returnStr += "return "; + } + } + String methodStr = getMethodStr(nativeMethod, paramSize, parameters); + String body = "{\n"; + body += returnStr; + body += methodStr; + body += "\n}"; + + BodyDeclaration bodyDeclaration = StaticJavaParser.parseBodyDeclaration(body); + InitializerDeclaration initializerDeclaration = (InitializerDeclaration)bodyDeclaration; + clone.setBody(initializerDeclaration.getBody()); + + NodeList parameters1 = clone.getParameters(); + String[] param = new String[parameters1.size()]; + for(int i = 0; i < parameters1.size(); i++) { + Parameter parameter = parameters1.get(i); + String nameAsString = parameter.getType().asString(); + param[i] = nameAsString; + } + List methodsBySignature = classDeclaration.getMethodsBySignature(clone.getNameAsString(), param); + if(methodsBySignature.isEmpty()) { + classDeclaration.addMember(clone); + } + } + + private static String getMethodStr(MethodDeclaration nativeMethod, int paramSize, NodeList parameters) { + String methodStr = nativeMethod.getNameAsString(); + String params = ""; + for(int i1 = 0; i1 < paramSize; i1++) { + String comma = ""; + if(i1 < paramSize - 1) { + comma = ", "; + } + Parameter parameter = parameters.get(i1); + String paramName = parameter.getNameAsString(); + params += paramName; + params += comma; + } + + methodStr += "(" + params + ");"; + return methodStr; + } + + private static void addImport(JParser jParser, CompilationUnit unit, Type elementType) { if(elementType.isClassOrInterfaceType()) { if(!JParserHelper.addMissingImportType(jParser, unit, elementType)) { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java index 3abb3141..ed0c976a 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java @@ -45,7 +45,7 @@ else if(size == 0) { if(!JParserHelper.containsMethod(classOrInterfaceDeclaration, nativeMethod)) { classOrInterfaceDeclaration.getMembers().add(nativeMethod); MethodCallExpr caller = IDLMethodParser.createCaller(nativeMethod); - caller.addArgument(IDLDefaultCodeParser.CPOINTER_METHOD); + caller.addArgument("(long)" + IDLDefaultCodeParser.CPOINTER_METHOD); BlockStmt blockStmt = deleteMethod.getBody().get(); blockStmt.addStatement(caller); idlParser.onIDLDeConstructorGenerated(jParser, idlClass, classOrInterfaceDeclaration, nativeMethod); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java index 310f5dbf..220f5f8b 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java @@ -36,7 +36,7 @@ public class IDLMethodParser { - static final String NATIVE_METHOD = "native_"; + public static final String NATIVE_METHOD = "internal_native_"; static final String GET_OBJECT_TEMPLATE = "{\n" + @@ -158,7 +158,9 @@ private static void setupMethod(IDLDefaultCodeParser idlParser, JParser jParser, } public static MethodDeclaration prepareNativeMethod(boolean isStatic, boolean isReturnValue, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, String methodName, String operator, ArrayList idlParameters) { - MethodDeclaration nativeMethodDeclaration = generateNativeMethod(isReturnValue, methodDeclaration, methodName); + NodeList methodParameters = methodDeclaration.getParameters(); + Type methodReturnType = methodDeclaration.getType(); + MethodDeclaration nativeMethodDeclaration = generateNativeMethod(isReturnValue, methodName, methodParameters, methodReturnType, methodDeclaration.isStatic()); if(!JParserHelper.containsMethod(classDeclaration, nativeMethodDeclaration)) { //Add native method if it does not exist classDeclaration.getMembers().add(nativeMethodDeclaration); @@ -166,8 +168,6 @@ public static MethodDeclaration prepareNativeMethod(boolean isStatic, boolean is MethodCallExpr caller = createCaller(nativeMethodDeclaration); - Type methodReturnType = methodDeclaration.getType(); - if(methodReturnType.isVoidType()) { // void types just call the method. IDLMethodParser.setupCallerParam(isStatic, false, caller, methodDeclaration.getParameters(), idlParameters); @@ -200,7 +200,7 @@ public static MethodCallExpr createCaller(MethodDeclaration nativeMethodDeclarat public static void setupCallerParam(boolean isStatic, boolean isReturnValue, MethodCallExpr caller, NodeList methodParameters, ArrayList idlParameters) { if(!isStatic) { - caller.addArgument(IDLDefaultCodeParser.CPOINTER_METHOD); + caller.addArgument("(long)" + IDLDefaultCodeParser.CPOINTER_METHOD); } for(int i = 0; i < methodParameters.size(); i++) { Parameter parameter = methodParameters.get(i); @@ -220,12 +220,12 @@ public static void setupCallerParam(boolean isStatic, boolean isReturnValue, Met } if(isArray && IDLHelper.getCArray(type.asClassOrInterfaceType().getNameAsString()) != null) { String methodCall = paramName + ".getPointer()"; - paramName = "(" + variableName + " != null ? " + methodCall + " : 0)"; + paramName = "(long)(" + variableName + " != null ? " + methodCall + " : 0)"; } else if(!IDLHelper.isString(type.asClassOrInterfaceType())) { //All methods must contain a base class to get its pointer String methodCall = paramName + ".getCPointer()"; - paramName = "(" + variableName + " != null ? " + methodCall + " : 0)"; + paramName = "(long)(" + variableName + " != null ? " + methodCall + " : 0)"; } } else if(type.isArrayType()) { @@ -336,20 +336,13 @@ private static String getFieldName(String type, int number, boolean isStatic) { } } - private static MethodDeclaration generateNativeMethod(boolean isReturnValue, MethodDeclaration methodDeclaration, String methodName) { - NodeList methodParameters = methodDeclaration.getParameters(); - Type methodReturnType = methodDeclaration.getType(); - boolean isStatic = methodDeclaration.isStatic(); - return generateNativeMethod(isReturnValue, methodName, methodParameters, methodReturnType, isStatic); - } - public static MethodDeclaration generateNativeMethod(boolean isReturnValue, String methodName, NodeList methodParameters, Type methodReturnType, boolean isStatic) { boolean isClassOrInterfaceType = methodReturnType.isClassOrInterfaceType(); // Clone some generated idl method settings MethodDeclaration nativeMethod = new MethodDeclaration(); nativeMethod.setName(NATIVE_METHOD + methodName); - nativeMethod.setModifiers(Modifier.createModifierList(Modifier.Keyword.PUBLIC, Modifier.Keyword.STATIC, Modifier.Keyword.NATIVE)); + nativeMethod.setModifiers(Modifier.createModifierList(Modifier.Keyword.PRIVATE, Modifier.Keyword.STATIC, Modifier.Keyword.NATIVE)); nativeMethod.removeBody(); if(!isStatic) { diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index fb3235e6..aa4bb1df 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -23,8 +23,8 @@ import com.github.javaparser.ast.type.ArrayType; import com.github.javaparser.ast.type.ClassOrInterfaceType; import com.github.javaparser.ast.type.Type; -import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.types.ResolvedArrayType; +import com.github.javaparser.resolution.types.ResolvedPrimitiveType; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; import com.github.xpenatan.jparser.core.JParser; @@ -37,9 +37,9 @@ import com.github.xpenatan.jparser.idl.IDLFile; import com.github.xpenatan.jparser.idl.IDLMethod; import com.github.xpenatan.jparser.idl.IDLParameter; +import com.github.xpenatan.jparser.idl.IDLReader; import com.github.xpenatan.jparser.idl.parser.IDLAttributeOperation; import com.github.xpenatan.jparser.idl.parser.IDLDefaultCodeParser; -import com.github.xpenatan.jparser.idl.IDLReader; import com.github.xpenatan.jparser.idl.parser.IDLMethodOperation; import java.io.File; import java.util.ArrayList; @@ -664,8 +664,6 @@ public void onParserComplete(JParser jParser, ArrayList parserItems ClassOrInterfaceDeclaration classDeclaration = classDeclarations.get(i1); convertNativeMethodLongType(classDeclaration); } - - List all = unit.findAll(MethodCallExpr.class); } } @@ -712,9 +710,21 @@ private void updateLongToInt(ClassOrInterfaceDeclaration classDeclaration, List< } for(int argI = 0; argI < arguments.size(); argI++) { Expression arg = arguments.get(argI); + boolean isLong = false; // used in public native methods + try { + ResolvedType resolvedType = arg.calculateResolvedType(); + if(resolvedType.isPrimitive()) { + ResolvedPrimitiveType primitive = resolvedType.asPrimitive(); + isLong = primitive.describe().equals("long"); + } + System.out.println(); + } + catch(Throwable t) { + System.out.println(); + } Parameter param = parameters.get(argI); Type type = param.getType(); - if(JParserHelper.isLong(type)) { + if(JParserHelper.isLong(type) || isLong) { Optional parentNode = arg.getParentNode(); if(parentNode.isPresent()) { Node node = parentNode.get(); From 7f93b5faf8ccf0c2a2344e763781acb185892425 Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 17 Aug 2024 08:45:25 -0300 Subject: [PATCH 069/186] Small improvement --- .../xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java index 996a05f0..58b4aa55 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java @@ -342,7 +342,10 @@ public void onParserComplete(JParser jParser, ArrayList parserItems } // Add additional method to call natives + makeNativesPublic(parserItems); + } + private void makeNativesPublic(ArrayList parserItems) { for(int i = 0; i < parserItems.size(); i++) { JParserItem parserItem = parserItems.get(i); String className = parserItem.className; From 7f4f3a0986bbb1b737c8ef35171c3d34ee1b8f44 Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 17 Aug 2024 08:57:38 -0300 Subject: [PATCH 070/186] remove println --- .../java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index aa4bb1df..a9a3da6c 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -717,10 +717,8 @@ private void updateLongToInt(ClassOrInterfaceDeclaration classDeclaration, List< ResolvedPrimitiveType primitive = resolvedType.asPrimitive(); isLong = primitive.describe().equals("long"); } - System.out.println(); } catch(Throwable t) { - System.out.println(); } Parameter param = parameters.get(argI); Type type = param.getType(); From 799b0db8c4f580cb264a5d817840feb65a3ae7f8 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 16:31:41 -0300 Subject: [PATCH 071/186] Add emscripten debug option --- .../builder/targets/EmscriptenTarget.java | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java index 96b404d5..18bc03ad 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java @@ -14,6 +14,9 @@ public class EmscriptenTarget extends DefaultBuildTarget { public IDLReader idlReader; + public static boolean DEBUG_BUILD = false; + public static boolean IS_WASM = true; + public boolean isStatic = false; public boolean compileGlueCode = true; @@ -38,11 +41,23 @@ public EmscriptenTarget(IDLReader idlReader) { cppCompiler.add(cppCompilerr); linkerCompiler.add(cppCompilerr); - libSuffix = ".wasm.js"; + if(IS_WASM) { + libSuffix = ".wasm.js"; + } + else { + libSuffix = ".js"; + } cppFlags.add("-c"); cppFlags.add("-std=c++17"); - cppFlags.add("-O3"); + + if(DEBUG_BUILD) { + cppFlags.add("-O0"); + cppFlags.add("-g2"); + } + else { + cppFlags.add("-O3"); + } } @Override @@ -100,8 +115,20 @@ protected boolean build(BuildConfig config, CustomFileDescriptor buildTargetTemp linkerFlags.add("EXPORTED_FUNCTIONS=['_free','_malloc']"); linkerFlags.add("-s"); linkerFlags.add("EXPORTED_RUNTIME_METHODS=['UTF8ToString']"); - linkerFlags.add("-s"); - linkerFlags.add("WASM=1"); + if(DEBUG_BUILD) { + linkerFlags.add("-s"); + linkerFlags.add("ASSERTIONS=1"); + linkerFlags.add("-s"); + linkerFlags.add("SAFE_HEAP=1"); + } + if(IS_WASM) { + linkerFlags.add("-s"); + linkerFlags.add("WASM=1"); + } + else { + linkerFlags.add("-s"); + linkerFlags.add("WASM=0"); + } linkerFlags.add("-s"); linkerFlags.add("SINGLE_FILE=1"); From 9af8d826e52bc2174fde069916749fd4cc0d9db1 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 16:34:43 -0300 Subject: [PATCH 072/186] update windows machine --- .github/workflows/build_and_upload.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 74451614..9e5e4218 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -16,7 +16,7 @@ env: jobs: build_windows: name: Build Windows - runs-on: ubuntu-latest + runs-on: windows-latest steps: - name: Cancel Previous Runs From ee89c5ef504a1dd32f3acd689f879b643d84dc58 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 16:39:12 -0300 Subject: [PATCH 073/186] update windows machine --- .github/workflows/build_and_upload.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 9e5e4218..fc3aad63 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -33,12 +33,7 @@ jobs: distribution: "zulu" java-version: 11 - - name: Set up MinGW - run: | - sudo apt install -y --force-yes mingw-w64 lib32z1 - - - name: Change wrapper permissions - run: chmod +x ./gradlew + - uses: msys2/setup-msys2@v2 - name: Build project run: ./gradlew build_project_windows64 From 6b9d583e6eb74eacb249919c02695c7dc75f8b1f Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 16:46:06 -0300 Subject: [PATCH 074/186] update windows machine --- .github/workflows/build_and_upload.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index fc3aad63..2a6ea7bf 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -35,6 +35,11 @@ jobs: - uses: msys2/setup-msys2@v2 + - name: Set up Visual Studio shell + uses: egor-tensin/vs-shell@v2 + with: + arch: x64 + - name: Build project run: ./gradlew build_project_windows64 From 686752c57b80d83d58ade9ac91a405c53a4ff9d0 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 16:56:29 -0300 Subject: [PATCH 075/186] update windows machine --- .github/workflows/build_and_upload.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 2a6ea7bf..5017d769 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -35,10 +35,7 @@ jobs: - uses: msys2/setup-msys2@v2 - - name: Set up Visual Studio shell - uses: egor-tensin/vs-shell@v2 - with: - arch: x64 + - uses: ilammy/msvc-dev-cmd@v1 - name: Build project run: ./gradlew build_project_windows64 From e5c9440af58aa18ba83240be136f1eafcc989787 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 17:04:35 -0300 Subject: [PATCH 076/186] update msvc cmd --- .../xpenatan/jparser/builder/targets/WindowsMSVCTarget.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java index 840f193a..fa3e8265 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java @@ -19,7 +19,8 @@ public WindowsMSVCTarget() { cppCompiler.add("cmd"); cppCompiler.add("/c"); - cppCompiler.add("vcvars64.bat"); + cppCompiler.add("vcvarsall.bat"); + cppCompiler.add("x64"); cppCompiler.add("&"); cppCompiler.add("cl"); compilerOutputCommand = "-Fo:"; @@ -38,7 +39,8 @@ public WindowsMSVCTarget() { @Override protected void setup(BuildConfig config) { - linkerCompiler.add("vcvars64.bat"); + linkerCompiler.add("vcvarsall.bat"); + linkerCompiler.add("x64"); linkerCompiler.add("&"); if(isStatic) { linkerCompiler.add("lib"); From 3c5a956461d23b51f8f4c861cbaff6e4842b0b58 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 17:11:38 -0300 Subject: [PATCH 077/186] update msvc cmd --- .github/workflows/build_and_upload.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 5017d769..b8cf9165 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -35,7 +35,9 @@ jobs: - uses: msys2/setup-msys2@v2 - - uses: ilammy/msvc-dev-cmd@v1 + - uses: TheMrMilchmann/setup-msvc-dev@v3 + with: + arch: x64 - name: Build project run: ./gradlew build_project_windows64 From 6056eb79ee8463e0c56acea8e8a5f3fede37e575 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 17:19:07 -0300 Subject: [PATCH 078/186] update msvc cmd --- .github/workflows/build_and_upload.yml | 5 ++--- example/lib/lib-build/src/main/java/BuildLib.java | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index b8cf9165..5a94841c 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -35,9 +35,8 @@ jobs: - uses: msys2/setup-msys2@v2 - - uses: TheMrMilchmann/setup-msvc-dev@v3 - with: - arch: x64 + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v2 - name: Build project run: ./gradlew build_project_windows64 diff --git a/example/lib/lib-build/src/main/java/BuildLib.java b/example/lib/lib-build/src/main/java/BuildLib.java index ddd27e02..eba7c2f9 100644 --- a/example/lib/lib-build/src/main/java/BuildLib.java +++ b/example/lib/lib-build/src/main/java/BuildLib.java @@ -32,8 +32,8 @@ public void onAddTarget(BuildToolOptions op, IDLReader idlReader, ArrayList Date: Sun, 18 Aug 2024 17:24:10 -0300 Subject: [PATCH 079/186] update msvc cmd --- .github/workflows/build_and_upload.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 5a94841c..5017d769 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -35,8 +35,7 @@ jobs: - uses: msys2/setup-msys2@v2 - - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v2 + - uses: ilammy/msvc-dev-cmd@v1 - name: Build project run: ./gradlew build_project_windows64 From 82687cb8865f4e401d4ffb6bd8e8e71c510617e3 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 17:35:20 -0300 Subject: [PATCH 080/186] update msvc cmd --- .github/workflows/build_and_upload.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 5017d769..e815c24b 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -35,7 +35,7 @@ jobs: - uses: msys2/setup-msys2@v2 - - uses: ilammy/msvc-dev-cmd@v1 + - uses: seanmiddleditch/gha-setup-vsdevenv@master - name: Build project run: ./gradlew build_project_windows64 From c3b6f1a8214e4055ed4e5afa27bb0cd046753935 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 17:41:14 -0300 Subject: [PATCH 081/186] update msvc cmd --- .github/workflows/build_and_upload.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index e815c24b..220ca2bf 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -35,7 +35,10 @@ jobs: - uses: msys2/setup-msys2@v2 - - uses: seanmiddleditch/gha-setup-vsdevenv@master + - uses: TheMrMilchmann/setup-msvc-dev@v3 + with: + arch: x64 + export-path-to-vcvarsall: vcvarsall.bat - name: Build project run: ./gradlew build_project_windows64 From ea5e6d998957921b40c669543a2bb79fe7183528 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 17:44:44 -0300 Subject: [PATCH 082/186] update msvc cmd --- .github/workflows/build_and_upload.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 220ca2bf..1d31bd4f 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -38,7 +38,7 @@ jobs: - uses: TheMrMilchmann/setup-msvc-dev@v3 with: arch: x64 - export-path-to-vcvarsall: vcvarsall.bat + export-path-to-vcvarsall: "" - name: Build project run: ./gradlew build_project_windows64 From d057bd52991b4d41d8e07b5ed269859cacf1e7c1 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 17:48:16 -0300 Subject: [PATCH 083/186] update msvc cmd --- .../xpenatan/jparser/builder/targets/WindowsMSVCTarget.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java index fa3e8265..c906c2ae 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java @@ -19,7 +19,7 @@ public WindowsMSVCTarget() { cppCompiler.add("cmd"); cppCompiler.add("/c"); - cppCompiler.add("vcvarsall.bat"); + cppCompiler.add("vcvarsall"); cppCompiler.add("x64"); cppCompiler.add("&"); cppCompiler.add("cl"); @@ -39,7 +39,7 @@ public WindowsMSVCTarget() { @Override protected void setup(BuildConfig config) { - linkerCompiler.add("vcvarsall.bat"); + linkerCompiler.add("vcvarsall"); linkerCompiler.add("x64"); linkerCompiler.add("&"); if(isStatic) { From 5a58969025e636b456a0ace19ab12af15ff4dfcc Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 17:51:55 -0300 Subject: [PATCH 084/186] update msvc cmd --- .github/workflows/build_and_upload.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 1d31bd4f..965be319 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -38,7 +38,7 @@ jobs: - uses: TheMrMilchmann/setup-msvc-dev@v3 with: arch: x64 - export-path-to-vcvarsall: "" + export-path-to-vcvarsall: $env:PATH - name: Build project run: ./gradlew build_project_windows64 From 7a741a4d72115b403d6e2f2930bc8aa8a7df57ab Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 17:55:31 -0300 Subject: [PATCH 085/186] update msvc cmd --- .github/workflows/build_and_upload.yml | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 965be319..c5d5acfd 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -40,14 +40,17 @@ jobs: arch: x64 export-path-to-vcvarsall: $env:PATH - - name: Build project - run: ./gradlew build_project_windows64 - - - name: Upload natives - uses: actions/upload-artifact@v4 - with: - name: windows-natives - path: ./example/lib/lib-build/build/c++/libs/ + - name: Test msvc + run: vcvarsall + +# - name: Build project +# run: ./gradlew build_project_windows64 +# +# - name: Upload natives +# uses: actions/upload-artifact@v4 +# with: +# name: windows-natives +# path: ./example/lib/lib-build/build/c++/libs/ build_linux: name: Build Linux From e5ca70c9fc9da945adc855aae75d682f21b6d7f7 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 17:58:34 -0300 Subject: [PATCH 086/186] update msvc cmd --- .github/workflows/build_and_upload.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index c5d5acfd..328d88d8 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -40,6 +40,12 @@ jobs: arch: x64 export-path-to-vcvarsall: $env:PATH + - name: Append the directory of 'vcvarsall.bat' to PATH environment variable + uses: myci-actions/export-env-var-powershell@1 + with: + name: PATH + value: $env:PATH;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build + - name: Test msvc run: vcvarsall From 128fc86159ded91ba11d1181afb8ad345fca5d68 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 17:59:56 -0300 Subject: [PATCH 087/186] update msvc cmd --- .github/workflows/build_and_upload.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 328d88d8..973d4239 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -38,13 +38,13 @@ jobs: - uses: TheMrMilchmann/setup-msvc-dev@v3 with: arch: x64 - export-path-to-vcvarsall: $env:PATH + export-path-to-vcvarsall: $env:PATH; - - name: Append the directory of 'vcvarsall.bat' to PATH environment variable - uses: myci-actions/export-env-var-powershell@1 - with: - name: PATH - value: $env:PATH;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build +# - name: Append the directory of 'vcvarsall.bat' to PATH environment variable +# uses: myci-actions/export-env-var-powershell@1 +# with: +# name: PATH +# value: $env:PATH;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build - name: Test msvc run: vcvarsall From 8bf68ee236aa0931d7d825d7cc7e6fddbb484e1d Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 18:01:08 -0300 Subject: [PATCH 088/186] update msvc cmd --- .github/workflows/build_and_upload.yml | 34 ++++++++++++-------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 973d4239..18de2592 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -38,25 +38,21 @@ jobs: - uses: TheMrMilchmann/setup-msvc-dev@v3 with: arch: x64 - export-path-to-vcvarsall: $env:PATH; - -# - name: Append the directory of 'vcvarsall.bat' to PATH environment variable -# uses: myci-actions/export-env-var-powershell@1 -# with: -# name: PATH -# value: $env:PATH;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build - - - name: Test msvc - run: vcvarsall - -# - name: Build project -# run: ./gradlew build_project_windows64 -# -# - name: Upload natives -# uses: actions/upload-artifact@v4 -# with: -# name: windows-natives -# path: ./example/lib/lib-build/build/c++/libs/ + + - name: Append the directory of 'vcvarsall.bat' to PATH environment variable + uses: myci-actions/export-env-var-powershell@1 + with: + name: PATH + value: $env:PATH;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build + + - name: Build project + run: ./gradlew build_project_windows64 + + - name: Upload natives + uses: actions/upload-artifact@v4 + with: + name: windows-natives + path: ./example/lib/lib-build/build/c++/libs/ build_linux: name: Build Linux From bef50657c1625d12d882f30051e310553098e093 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 18:07:29 -0300 Subject: [PATCH 089/186] update msvc target --- .../xpenatan/jparser/builder/targets/WindowsMSVCTarget.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java index c906c2ae..e190a20a 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java @@ -39,6 +39,8 @@ public WindowsMSVCTarget() { @Override protected void setup(BuildConfig config) { + linkerCompiler.add("cmd"); + linkerCompiler.add("/c"); linkerCompiler.add("vcvarsall"); linkerCompiler.add("x64"); linkerCompiler.add("&"); From 77cc2aae5064c909ffb10cb2698d1b440a4bfc19 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 18:16:02 -0300 Subject: [PATCH 090/186] update workflow --- .github/workflows/build_and_upload.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 18de2592..2a7a1d6c 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -33,9 +33,11 @@ jobs: distribution: "zulu" java-version: 11 - - uses: msys2/setup-msys2@v2 + - name: Set up MinGW + uses: msys2/setup-msys2@v2 - - uses: TheMrMilchmann/setup-msvc-dev@v3 + - name: Set up Developer Command Prompt + uses: TheMrMilchmann/setup-msvc-dev@v3 with: arch: x64 From cedf493ce90ab7798b6e0c0ae84fd2702e6eaac1 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 20:30:19 -0300 Subject: [PATCH 091/186] update MSVC target to use native multicore build --- .../jparser/builder/DefaultBuildTarget.java | 2 +- .../builder/targets/WindowsMSVCTarget.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java index bc4d66b9..140808d6 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java @@ -95,7 +95,7 @@ else if(!shouldCompile && shouldLink) { } } - private boolean compile(BuildConfig config, CustomFileDescriptor buildTargetTemp, ArrayList cppFiles) { + protected boolean compile(BuildConfig config, CustomFileDescriptor buildTargetTemp, ArrayList cppFiles) { boolean retFlag = false; String compiledPaths = ""; diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java index e190a20a..c3d73c92 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/WindowsMSVCTarget.java @@ -2,6 +2,8 @@ import com.github.xpenatan.jparser.builder.BuildConfig; import com.github.xpenatan.jparser.builder.DefaultBuildTarget; +import com.github.xpenatan.jparser.core.util.CustomFileDescriptor; +import java.util.ArrayList; public class WindowsMSVCTarget extends DefaultBuildTarget { @@ -58,4 +60,17 @@ protected void setup(BuildConfig config) { linkerCompiler.add("/NOLOGO"); linkerCompiler.add("/MACHINE:X64"); } + + @Override + protected boolean compile(BuildConfig config, CustomFileDescriptor buildTargetTemp, ArrayList cppFiles) { + boolean multiCoreCompile = this.multiCoreCompile; + this.multiCoreCompile = false; + if(multiCoreCompile) { + // Use native MSVC multi core support + cppCompiler.add("/MP"); + } + boolean compile = super.compile(config, buildTargetTemp, cppFiles); + this.multiCoreCompile = multiCoreCompile; + return compile; + } } From dd4b1d294ae783330ea914c1a503a02df4e2accc Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 21:29:39 -0300 Subject: [PATCH 092/186] Add array get note --- example/lib/lib-build/src/main/cpp/TestLib.idl | 1 + 1 file changed, 1 insertion(+) diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index e3bc8939..c34bb00f 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -9,6 +9,7 @@ // TestConstructorClass works because it have different parameter size. From the [BUG] above, don't use string or it will fail at runtime. // * Arrays parameters for example "void method(int[] array)" is converted to IDLIntArray class object behind the scene because interacting with array is better using native code. // For custom types is better to use typedef. See TestObjectClassArray in CustomCode.h +// * Array get_ shape the same object for every index. Don't keep object reference. interface TestObjectClass { From 2c12c697288553ac6d49fafbdbebec0bc199d6f3 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 21:57:41 -0300 Subject: [PATCH 093/186] Test String ref and value --- .../xpenatan/jparser/example/app/TestLib.java | 32 +++++++++++++++++++ .../lib/lib-build/src/main/cpp/TestLib.idl | 1 + .../src/main/cpp/source/TestLib/src/TestLib.h | 1 + 3 files changed, 34 insertions(+) diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java index c554c8e4..fb151b37 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java @@ -4,6 +4,7 @@ import com.github.xpenatan.jparser.example.testlib.TestMethodClass; import com.github.xpenatan.jparser.example.testlib.TestObjectClass; import com.github.xpenatan.jparser.example.testlib.TestObjectClassArray; +import com.github.xpenatan.jparser.example.testlib.idl.helper.IDLString; public class TestLib { @@ -207,6 +208,37 @@ private static boolean testMethodClass() { array.dispose(); test.dispose(); } + { + TestMethodClass test = new TestMethodClass(); + try { + String strValue01 = "Hello"; + test.setMethod05(strValue01); + String stringValue = test.getStrValue01().data(); + if(!(strValue01.equals(stringValue))) { + throw new RuntimeException("strValue01.equals(stringValue)"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + } + + } + { + TestMethodClass test = new TestMethodClass(); + try { + String strValue01 = "RefHello"; + test.setMethod05(strValue01); + IDLString refStrValue01 = test.getRefStrValue01(); + String stringValue = refStrValue01.data(); + if(!(strValue01.equals(stringValue))) { + throw new RuntimeException("strValue01.equals(stringValue)"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + } + + } return true; } diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index c34bb00f..2c134be0 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -100,6 +100,7 @@ interface TestMethodClass { float getFloatValue02(); float getBoolValue01(); [Const, Value] IDLStringView getStrValue01(); + [Const, Ref] IDLString getRefStrValue01(); [Const] TestObjectClass getPointerObject01(); TestObjectClass getPointerObject02(); [Const, Ref] TestObjectClass getRefObject01(); diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h index 72ba95fc..b260366f 100644 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h @@ -188,6 +188,7 @@ class TestMethodClass { float getFloatValue02() { return floatValue02; }; bool getBoolValue01() { return boolValue01; }; const char* getStrValue01() { return strValue01.c_str(); }; + const string& getRefStrValue01() { return strValue01; }; const TestObjectClass* getPointerObject01() { return pointerObject01; }; TestObjectClass* getPointerObject02() { return pointerObject02; }; const TestObjectClass& getRefObject01() { return refObject01; }; From 437218d86da5bd2ac62571cc1e3a33a7a1450565 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 18 Aug 2024 23:00:40 -0300 Subject: [PATCH 094/186] Small callback idl improvement. Remove old test classes --- .../lib/lib-build/src/main/cpp/TestLib.idl | 157 ++-------------- .../cpp/source/TestLib/src/DefaultInterface.h | 12 -- .../source/TestLib/src/DefaultParamsClass.cpp | 11 -- .../source/TestLib/src/DefaultParamsClass.h | 17 -- .../cpp/source/TestLib/src/InterfaceClass.h | 11 -- .../cpp/source/TestLib/src/NormalClass.cpp | 168 ------------------ .../main/cpp/source/TestLib/src/NormalClass.h | 92 ---------- .../cpp/source/TestLib/src/OperatorClass.cpp | 10 -- .../cpp/source/TestLib/src/OperatorClass.h | 9 - .../cpp/source/TestLib/src/ParentClass.cpp | 21 --- .../main/cpp/source/TestLib/src/ParentClass.h | 11 -- .../cpp/source/TestLib/src/ReturnClass.cpp | 6 - .../main/cpp/source/TestLib/src/ReturnClass.h | 8 - .../src/main/cpp/source/TestLib/src/TestLib.h | 5 + .../TestLib/src/subpackage/ParamData.cpp | 1 - .../source/TestLib/src/subpackage/ParamData.h | 11 -- 16 files changed, 21 insertions(+), 529 deletions(-) delete mode 100644 example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultInterface.h delete mode 100644 example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultParamsClass.cpp delete mode 100644 example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultParamsClass.h delete mode 100644 example/lib/lib-build/src/main/cpp/source/TestLib/src/InterfaceClass.h delete mode 100644 example/lib/lib-build/src/main/cpp/source/TestLib/src/NormalClass.cpp delete mode 100644 example/lib/lib-build/src/main/cpp/source/TestLib/src/NormalClass.h delete mode 100644 example/lib/lib-build/src/main/cpp/source/TestLib/src/OperatorClass.cpp delete mode 100644 example/lib/lib-build/src/main/cpp/source/TestLib/src/OperatorClass.h delete mode 100644 example/lib/lib-build/src/main/cpp/source/TestLib/src/ParentClass.cpp delete mode 100644 example/lib/lib-build/src/main/cpp/source/TestLib/src/ParentClass.h delete mode 100644 example/lib/lib-build/src/main/cpp/source/TestLib/src/ReturnClass.cpp delete mode 100644 example/lib/lib-build/src/main/cpp/source/TestLib/src/ReturnClass.h delete mode 100644 example/lib/lib-build/src/main/cpp/source/TestLib/src/subpackage/ParamData.cpp delete mode 100644 example/lib/lib-build/src/main/cpp/source/TestLib/src/subpackage/ParamData.h diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index 2c134be0..f2c8124e 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -131,16 +131,18 @@ interface TestStaticMethodClass { }; interface CallbackClass { - [Const] void onVoidCallback([Ref] TestObjectClass refData, TestObjectClass pointerData); - [Const] long onIntCallback(long intValue01, long intValue02); - [Const] float onFloatCallback(float floatValue01, float floatValue02); - [Const] boolean onBoolCallback(boolean boolValue01); - [Const] void onStringCallback([Const] DOMString strValue01); + long addInt(long a, long b); }; [JSImplementation="CallbackClass"] interface CallbackClassImpl { void CallbackClassImpl(); + + [Const] void onVoidCallback([Ref] TestObjectClass refData, TestObjectClass pointerData); + [Const] long onIntCallback(long intValue01, long intValue02); + [Const] float onFloatCallback(float floatValue01, float floatValue02); + [Const] boolean onBoolCallback(boolean boolValue01); + [Const] void onStringCallback([Const] DOMString strValue01); }; CallbackClassImpl implements CallbackClass; @@ -149,6 +151,14 @@ interface DefaultCallbackClass { }; DefaultCallbackClass implements CallbackClass; +[JSImplementation="DefaultCallbackClass"] +interface DefaultCallbackClassImpl { + void DefaultCallbackClassImpl(); + + [Const] long onIntCallback(long intValue01, long intValue02); +}; +DefaultCallbackClassImpl implements DefaultCallbackClass; + interface TestCallbackClass { void TestCallbackClass(); @@ -184,139 +194,4 @@ enum TestEnumLib { "TEST_DEFAULT", "TEST_FIRST", "TEST_SECOND" -}; - -// ########################################## - -//interface ParentClass { -// float addFloatValue(float a, float b); -// boolean invertBoolean(boolean value); -//}; -// -//interface NormalClass { -// [BoundsChecked] attribute long[] intArray; -// [Value] attribute ReturnClass[] valueArray; -// attribute ReturnClass[] pointerArray; -// attribute long hiddenInt; -// [Value] attribute ReturnClass valueReturnClass; -// attribute ReturnClass pointerReturnClass; -// attribute ReturnClass nullPointerReturnClass; -// -// static attribute long hiddenInt_static; -// [Value] static attribute ReturnClass valueReturnClass_static; -// static attribute ReturnClass pointerReturnClass_static; -// static attribute ReturnClass nullPointerReturnClass_static; -// -// void NormalClass(); -// void NormalClass(long c, [Ref]ParamData refParamClass); -// void NormalClass(EnumInNamespace nameSpaceEnum); -// -// long getVersion(); -//// Emscripten don't allow param by value -//// void NormalClass(ParamData pointerParamData, [Ref]ParamData refParamData, [Value]ParamData valueParamData); -// -//// void setString(DOMString text); -//// static DOMString addString(DOMString text); -//// [Value] static ReturnClass getStaticReturnValueClass(ParamData paramData); -// [Value]ReturnClass getReturnValueClass(ParamData paramData); -// -// static long subIntValue(long a, long b, optional long subValue); -// long addIntValue(long a, long b); -// [Ref]ReturnClass getReturnRefClass(); -// [Value]ReturnClass getReturnValueObject(); -//// ReturnClass getReturnPointerClass(); -//// ReturnClass getReturnNullPointerClass(); -// void refParam([Ref]ParamData refParamOne, [Ref]ParamData refParamTwo, [Ref]ParamData refParamThree); -//// void pointerParam(ParamData paramData); -// -// // Emscripten don't allow param by value -//// void valueParam([Value]ParamData paramData); -// -//// void addIntArrayItems(long [] array); -// -// void callInterface([Ref]InterfaceClass obj); -// -// long enumParam(EnumLib value); -// -// void enumVoidParam(EnumLib value); -// -// EnumLib enumReturn(long value); -// -// boolean printText(long dummyParam, [Const]DOMString text); -// -// void setArray(float[] array); -// -// void setString([Ref] IDLString text); -// [Ref] IDLString getString(); -// [Value] IDLString getStringValue(); -// -// void setVoidParam(any param); -// any getVoidParam(); -//}; -//NormalClass implements ParentClass; -// -//interface DefaultParamsClass { -// void DefaultParamsClass(long a, long b, optional float c, optional float d); -// -// void defaultMethodParams(long a, long b, optional float c, optional float d); -//}; -// -//[NoDelete] -//interface ReturnClass { -// void ReturnClass(); -// -// attribute float value; -// -// [Operator="=", Ref] ReturnClass copy([Ref]ReturnClass value); -//}; -// -//interface OperatorClass { -// void OperatorClass(); -// -// attribute float value; -// -// [Operator="=", Ref] OperatorClass copy([Ref]OperatorClass value); -//}; -// -//interface ParamData { -// void ParamData(); -// attribute long intData; -// attribute float floatData; -//}; -// -//interface InterfaceClass { -// void onParamCall([Ref]ParamData data); -//}; -// -//[JSImplementation="InterfaceClass"] -//interface InterfaceClassImpl { -// void InterfaceClassImpl(); -// [Const] void onParamCall([Ref]ParamData data); -//}; -// -//interface DefaultInterface { -// void DefaultInterface(); -//}; -//DefaultInterface implements InterfaceClass; -// -//enum EnumLib { -// "FIRST", -// "SECOND" -//}; -// -//enum EnumTwoLib { -// "EnumTwoLib_THIRD", -// "EnumTwoLib_FOURTH" -//}; -// -//enum EnumWithinClass { -// "NormalClass::e_val" -//}; -// -//enum EnumClassWithinClass { -// "EnumClassWithinClass::testEnum" -//}; -// -//enum EnumInNamespace { -// "EnumInNamespace::e_namespace_val" -//}; \ No newline at end of file +}; \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultInterface.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultInterface.h deleted file mode 100644 index 11619fbd..00000000 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultInterface.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "InterfaceClass.h" - -class DefaultInterface : public InterfaceClass -{ -public: - virtual void onParamCall(ParamData& data) const { - data.intData = 99; - data.floatData = 99.9; - } -}; diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultParamsClass.cpp b/example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultParamsClass.cpp deleted file mode 100644 index 6b972041..00000000 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultParamsClass.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "DefaultParamsClass.h" - -DefaultParamsClass::DefaultParamsClass(int a, int b, float c, float d) -{ - -} - -void DefaultParamsClass::defaultMethodParams(int a, int b, float c, float d) -{ - -} \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultParamsClass.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultParamsClass.h deleted file mode 100644 index 91f7ded9..00000000 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/DefaultParamsClass.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "ParentClass.h" -#include "subpackage/ParamData.h" -#include "ReturnClass.h" -#include "InterfaceClass.h" -#include "OperatorClass.h" - -class DefaultParamsClass -{ - - -public: - DefaultParamsClass(int a, int b, float c = 0, float d = 0); - - void defaultMethodParams(int a, int b, float c = 0, float d = 0); -}; diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/InterfaceClass.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/InterfaceClass.h deleted file mode 100644 index 8528ac82..00000000 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/InterfaceClass.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "subpackage/ParamData.h" - -class InterfaceClass -{ -public: - virtual ~InterfaceClass() {} - - virtual void onParamCall(ParamData& data) const = 0; -}; diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/NormalClass.cpp b/example/lib/lib-build/src/main/cpp/source/TestLib/src/NormalClass.cpp deleted file mode 100644 index 296027b8..00000000 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/NormalClass.cpp +++ /dev/null @@ -1,168 +0,0 @@ -#include "NormalClass.h" -#include - -NormalClass::NormalClass() -{ - valueReturnClass.value = 10; - nullPointerReturnClass = 0; - pointerReturnClass = new ReturnClass(); -} - -NormalClass::NormalClass(EnumNamespace::EnumInNamespace enumParam) -{ - -} - -NormalClass::NormalClass(int c, ParamData & refParamData) -{ - valueReturnClass.value = 10; - nullPointerReturnClass = 0; - pointerReturnClass = new ReturnClass(); -} - -NormalClass::NormalClass(ParamData * pointerParamData, ParamData & refParamData, ParamData valueParamData) -{ - valueReturnClass.value = 10; - nullPointerReturnClass = 0; - pointerReturnClass = new ReturnClass(); -} - -int NormalClass::getVersion() -{ - return 7; -} - -void NormalClass::setString(char* text) -{ - -} - -int NormalClass::subIntValue(int a, int b, int subValue) -{ - return (a - b) - subValue; -} - -int NormalClass::addIntValue(int a, int b) -{ - return (a + b) * hiddenInt * hiddenParentInt; -} - -ReturnClass NormalClass::getStaticReturnValueClass(ParamData * paramData) -{ - ReturnClass temp; - return temp; -} - -ReturnClass NormalClass::getReturnValueClass(ParamData * paramData) -{ - return valueReturnClass; -} - -ReturnClass NormalClass::getReturnValueObject() -{ - return valueReturnClass; -} - -ReturnClass & NormalClass::getReturnRefClass() -{ - return valueReturnClass; -} - -ReturnClass * NormalClass::getReturnPointerClass() -{ - return pointerReturnClass; -} - -ReturnClass * NormalClass::getReturnNullPointerClass() -{ - return nullPointerReturnClass; -} - -void NormalClass::refParam(ParamData & refParamOne, ParamData & refParamTwo, ParamData & refParamThree) -{ -} - -void NormalClass::pointerParam(ParamData * pointerParamData) -{ -} - -void NormalClass::valueParam(ParamData valueParamData) -{ -} - -void NormalClass::addIntArrayItems(int* array, int valueToAdd) -{ - int value = array[0]; - array[0] = value + valueToAdd; -} - -void NormalClass::callInterface(InterfaceClass & obj) -{ - obj.onParamCall(data); -} - -int NormalClass::enumParam(EnumLib value) -{ - if(value == FIRST) { - return 111; - } - if(value == SECOND) { - return 222; - } - return 0; -} - -void NormalClass::enumVoidParam(EnumLib value) -{ -} - -EnumLib NormalClass::enumReturn(int value) -{ - if(value == 1) { - return FIRST; - } - if(value == 2) { - return SECOND; - } - return DEFAULT; -} - -void NormalClass::enumTwoVoidParam(EnumTwoLib value) -{ -} - -bool NormalClass::printText(int dummyParam, const char* text) -{ - std::cout << text << std::endl; - return true; -} - -void NormalClass::setArray(float* array) -{ - array[0] = 1.2; -} - -void NormalClass::setString(std::string& text) -{ -} - -std::string& NormalClass::getString() -{ - std::string* test = new std::string("HELLO STRING"); - return *test; -} - -std::string NormalClass::getStringValue() -{ - std::string test = "HELLO STRING VALUE"; - return test; -} - -void NormalClass::setVoidParam(void* param) -{ -} - -void* NormalClass::getVoidParam() -{ - return NULL; -} diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/NormalClass.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/NormalClass.h deleted file mode 100644 index 999076e8..00000000 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/NormalClass.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#include "ParentClass.h" -#include "subpackage/ParamData.h" -#include "ReturnClass.h" -#include "InterfaceClass.h" -#include -#include -#include - -enum EnumLib : int { - DEFAULT = 7, - FIRST, - SECOND, -}; - -enum EnumTwoLib { - EnumTwoLib_THIRD = 15, - EnumTwoLib_FOURTH -}; - -namespace EnumNamespace { - enum EnumInNamespace { - e_namespace_val = 78 - }; -}; - -class NormalClass : public ParentClass -{ - -private: - ParamData data; - -public: - int intArray[3]; - ReturnClass valueArray[3]; - ReturnClass* pointerArray[3]; - - enum EnumWithinClass { - e_val = 34 - }; - - enum class EnumClassWithinClass { - testEnum = 35 - }; - - int hiddenInt = 1; - - ReturnClass valueReturnClass; - ReturnClass * pointerReturnClass; - ReturnClass * nullPointerReturnClass; - - inline static int hiddenInt_static = 0; - inline static ReturnClass valueReturnClass_static; - inline static ReturnClass * pointerReturnClass_static = new ReturnClass(); - inline static ReturnClass * nullPointerReturnClass_static = NULL; - - NormalClass(); - NormalClass(EnumNamespace::EnumInNamespace); - NormalClass(int c, ParamData & refParamData); - NormalClass(ParamData * pointerParamData, ParamData & refParamData, ParamData valueParamData); - - int getVersion(); - void setString(char* text); - static int subIntValue(int a, int b, int subValue = 0); - int addIntValue(int a, int b); - - static ReturnClass getStaticReturnValueClass(ParamData * paramData); - ReturnClass getReturnValueClass(ParamData * paramData); - ReturnClass getReturnValueObject(); - - ReturnClass & getReturnRefClass(); - ReturnClass * getReturnPointerClass(); - ReturnClass * getReturnNullPointerClass(); - void refParam(ParamData & refParamOne, ParamData & refParamTwo, ParamData & refParamThree); - void pointerParam(ParamData * pointerParamData); - void valueParam(ParamData valueParamData); - void addIntArrayItems(int* array, int valueToAdd); - void callInterface(InterfaceClass & obj); - int enumParam(EnumLib value); - void enumVoidParam(EnumLib value); - EnumLib enumReturn(int value); - void enumTwoVoidParam(EnumTwoLib value); - bool printText(int dummyParam, const char* text); - void setArray(float* array); - - void setString(std::string& text); - std::string& getString(); - std::string getStringValue(); - void setVoidParam(void* param); - void* getVoidParam(); -}; diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/OperatorClass.cpp b/example/lib/lib-build/src/main/cpp/source/TestLib/src/OperatorClass.cpp deleted file mode 100644 index ef3e1d2d..00000000 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/OperatorClass.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "OperatorClass.h" - -OperatorClass& OperatorClass::operator=(const OperatorClass& other) { - this->value = other.value; - return *this; -} - -float OperatorClass::operator+(OperatorClass toAdd) { - return value + toAdd.value; -} \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/OperatorClass.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/OperatorClass.h deleted file mode 100644 index 8997f124..00000000 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/OperatorClass.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -class OperatorClass -{ -public: - float value = 0; - OperatorClass& operator=(const OperatorClass& other); - float operator+(OperatorClass toAdd); -}; \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/ParentClass.cpp b/example/lib/lib-build/src/main/cpp/source/TestLib/src/ParentClass.cpp deleted file mode 100644 index dcad3c9b..00000000 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/ParentClass.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "ParentClass.h" - -ParentClass::ParentClass() -{ - int a = 1; - int b = 2; - int c = a + b; - c++; -} - -float ParentClass::addFloatValue(float a, float b) -{ - return (a + b) * hiddenParentInt; -// return (a + b); -} - -bool ParentClass::invertBoolean(bool value) -{ - return !(bool)(value * hiddenParentInt); -// return !value; -} \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/ParentClass.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/ParentClass.h deleted file mode 100644 index 681170ab..00000000 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/ParentClass.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -class ParentClass -{ -protected: - int hiddenParentInt = 1; -public: - ParentClass(); - float addFloatValue(float a, float b); - bool invertBoolean(bool value); -}; diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/ReturnClass.cpp b/example/lib/lib-build/src/main/cpp/source/TestLib/src/ReturnClass.cpp deleted file mode 100644 index 1f6d145d..00000000 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/ReturnClass.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "ReturnClass.h" - -ReturnClass& ReturnClass::operator=(const ReturnClass& other) { - this->value = other.value; - return *this; -} \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/ReturnClass.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/ReturnClass.h deleted file mode 100644 index ee7dd64e..00000000 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/ReturnClass.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -class ReturnClass -{ -public: - float value = 0; - ReturnClass& operator=(const ReturnClass& other); -}; diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h index b260366f..a2a62a2e 100644 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h @@ -263,6 +263,11 @@ class CallbackClass virtual float onFloatCallback(float floatValue01, float Value02) const = 0; virtual bool onBoolCallback(bool boolValue01) const = 0; virtual void onStringCallback(const char* strValue01) const = 0; + + int addInt(int a, int b) + { + return a + b; + } }; class DefaultCallbackClass : public CallbackClass diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/subpackage/ParamData.cpp b/example/lib/lib-build/src/main/cpp/source/TestLib/src/subpackage/ParamData.cpp deleted file mode 100644 index 5da04347..00000000 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/subpackage/ParamData.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "ParamData.h" \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/subpackage/ParamData.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/subpackage/ParamData.h deleted file mode 100644 index ec36b2e6..00000000 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/subpackage/ParamData.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef PARAMDATA_H -#define PARAMDATA_H - -class ParamData -{ -public: - int intData = 1; - float floatData = 3; -}; - -#endif //PARAMDATA_H From d5a3b2badba6251a4a214e3ed98edb5fbd912dd6 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 22 Aug 2024 19:44:51 -0300 Subject: [PATCH 095/186] Add callback test --- .../xpenatan/jparser/example/app/TestLib.java | 124 +++++++++++++- .../example/testlib/CallbackClass.java | 9 + .../example/testlib/CallbackClassManual.java | 159 ++++++++++++++++++ .../lib/lib-build/src/main/cpp/TestLib.idl | 6 +- .../src/main/cpp/source/TestLib/src/TestLib.h | 6 +- jParser/base/src/main/java/idl/IDLBase.java | 8 + 6 files changed, 303 insertions(+), 9 deletions(-) create mode 100644 example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClass.java create mode 100644 example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java index fb151b37..cfef0fe3 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java @@ -1,5 +1,7 @@ package com.github.xpenatan.jparser.example.app; +import com.github.xpenatan.jparser.example.testlib.CallbackClassManual; +import com.github.xpenatan.jparser.example.testlib.TestCallbackClass; import com.github.xpenatan.jparser.example.testlib.TestConstructorClass; import com.github.xpenatan.jparser.example.testlib.TestMethodClass; import com.github.xpenatan.jparser.example.testlib.TestObjectClass; @@ -17,6 +19,7 @@ public static boolean test() { boolean methodTest = testMethodClass(); boolean staticMethodTest = testStaticMethodClass(); boolean callbackTest = testCallbackClass(); + boolean callbackTestManual = testCallbackClassManual(); System.out.println("constructorTest: " + constructorTest); System.out.println("stringConstructorTest: " + stringConstructorTest); @@ -27,7 +30,7 @@ public static boolean test() { System.out.println("staticMethodTest: " + staticMethodTest); System.out.println("callbackTest: " + callbackTest); return constructorTest && stringConstructorTest && attributeTest && staticAttributeTest - && attributeArrayTest && methodTest && staticMethodTest && callbackTest; + && attributeArrayTest && methodTest && staticMethodTest && callbackTest && callbackTestManual; } private static boolean testConstructorClass() { @@ -220,8 +223,9 @@ private static boolean testMethodClass() { } catch(Throwable e) { e.printStackTrace(); test.dispose(); + return false; } - + test.dispose(); } { TestMethodClass test = new TestMethodClass(); @@ -236,8 +240,9 @@ private static boolean testMethodClass() { } catch(Throwable e) { e.printStackTrace(); test.dispose(); + return false; } - + test.dispose(); } return true; } @@ -249,8 +254,121 @@ private static boolean testStaticMethodClass() { } private static boolean testCallbackClass() { + return true; + } + private static boolean testCallbackClassManual() { + { + TestCallbackClass test = new TestCallbackClass(); + try { + boolean[] internal_onVoidCallback = { false }; + CallbackClassManual callback = new CallbackClassManual() { + @Override + public void internal_onVoidCallback(long refData, long pointerData) { + internal_onVoidCallback[0] = true; + } + }; + test.callVoidCallback(callback); + if(!(internal_onVoidCallback[0] == true)) { + throw new RuntimeException("internal_onVoidCallback[0] == true"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } + { + TestCallbackClass test = new TestCallbackClass(); + try { + boolean[] internal_onIntCallback = { false }; + CallbackClassManual callback = new CallbackClassManual() { + @Override + public int internal_onIntCallback(int intValue01, int intValue02) { + internal_onIntCallback[0] = true; + return 0; + } + }; + test.callIntCallback(callback); + if(!(internal_onIntCallback[0] == true)) { + throw new RuntimeException("internal_onIntCallback[0] == true"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } + { + TestCallbackClass test = new TestCallbackClass(); + try { + boolean[] internal_onFloatCallback = { false }; + CallbackClassManual callback = new CallbackClassManual() { + @Override + public float internal_onFloatCallback(float floatValue01, float floatValue02) { + internal_onFloatCallback[0] = true; + return 0; + } + }; + test.callFloatCallback(callback); + if(!(internal_onFloatCallback[0] == true)) { + throw new RuntimeException("internal_onFloatCallback[0] == true"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } + { + TestCallbackClass test = new TestCallbackClass(); + try { + boolean[] internal_onBoolCallback = { false }; + CallbackClassManual callback = new CallbackClassManual() { + @Override + public boolean internal_onBoolCallback(boolean boolValue01) { + internal_onBoolCallback[0] = true; + return false; + } + }; + test.callBoolCallback(callback); + if(!(internal_onBoolCallback[0] == true)) { + throw new RuntimeException("internal_onBoolCallback[0] == true"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } + { + TestCallbackClass test = new TestCallbackClass(); + try { + String text = "HELLO_WORLD"; + test.get_strValue01().append(text); + final String[] internal_onStringCallback = new String[1]; + CallbackClassManual callback = new CallbackClassManual() { + @Override + public void internal_onStringCallback(String strValue01) { + internal_onStringCallback[0] = strValue01; + } + }; + test.callStringCallback(callback); + if(!(text.equals(internal_onStringCallback[0]) == true)) { + throw new RuntimeException("text.equals(internal_onStringCallback[0]) == true"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } return true; } } \ No newline at end of file diff --git a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClass.java b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClass.java new file mode 100644 index 00000000..919dbd40 --- /dev/null +++ b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClass.java @@ -0,0 +1,9 @@ +package com.github.xpenatan.jparser.example.testlib; + +import idl.IDLBase; + +public class CallbackClass extends IDLBase { + + public CallbackClass(byte b, char c) { + } +} \ No newline at end of file diff --git a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java new file mode 100644 index 00000000..983f9e72 --- /dev/null +++ b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java @@ -0,0 +1,159 @@ +package com.github.xpenatan.jparser.example.testlib; +import idl.IDLBase; + +public class CallbackClassManual extends CallbackClass { + + /*[-JNI;-NATIVE] + static jclass CallbackClassManual_CLASS = 0; + static jmethodID onVoidCallback_ID = 0; + static jmethodID onIntCallback_ID = 0; + static jmethodID onFloatCallback_ID = 0; + static jmethodID onBoolCallback_ID = 0; + static jmethodID onStringCallback_ID = 0; + + class CallbackClassManual : public CallbackClass { + private: + JNIEnv* env; + jobject obj; + public: + CallbackClassManual( JNIEnv* env, jobject obj ) { + this->env = env; + this->obj = obj; + } + virtual void onVoidCallback(TestObjectClass& refData, TestObjectClass* pointerData) const { + env->CallVoidMethod(obj, onVoidCallback_ID, (jlong)&refData, (jlong)pointerData); + } + virtual int onIntCallback(int intValue01, int intValue02) const { + return env->CallIntMethod(obj, onIntCallback_ID, intValue01, intValue02); + } + virtual float onFloatCallback(float floatValue01, float floatValue02) const { + return env->CallFloatMethod(obj, onFloatCallback_ID, floatValue01, floatValue02); + } + virtual bool onBoolCallback(bool boolValue01) const { + return env->CallBooleanMethod(obj, onBoolCallback_ID, boolValue01); + } + virtual void onStringCallback(const char* strValue01) const { + jstring jstrBuf = env->NewStringUTF(strValue01); + env->CallVoidMethod(obj, onStringCallback_ID, jstrBuf); + } + }; + */ + + /*[-TEAVM;-ADD] + @org.teavm.jso.JSFunctor + public interface onVoidCallback extends org.teavm.jso.JSObject { + void onVoidCallback(int refData, int pointerData); + } + */ + /*[-TEAVM;-ADD] + @org.teavm.jso.JSFunctor + public interface onIntCallback extends org.teavm.jso.JSObject { + int onIntCallback(int intValue01, int intValue02); + } + */ + /*[-TEAVM;-ADD] + @org.teavm.jso.JSFunctor + public interface onFloatCallback extends org.teavm.jso.JSObject { + float onFloatCallback(float floatValue01, float floatValue02); + } + */ + /*[-TEAVM;-ADD] + @org.teavm.jso.JSFunctor + public interface onBoolCallback extends org.teavm.jso.JSObject { + boolean onBoolCallback(boolean boolValue01); + } + */ + /*[-TEAVM;-ADD] + @org.teavm.jso.JSFunctor + public interface onStringCallback extends org.teavm.jso.JSObject { + void onStringCallback(int strValue01); + } + */ + + /*[-TEAVM;-REPLACE] + public CallbackClassManual() { + super((byte)0, (char)0); + onVoidCallback onVoidCallback = new onVoidCallback() { + @Override + public void onVoidCallback(int refData, int pointerData) { + internal_onVoidCallback(refData, pointerData); + } + }; + onIntCallback onIntCallback = new onIntCallback() { + @Override + public int onIntCallback(int intValue01, int intValue02) { + return internal_onIntCallback(intValue01, intValue02); + } + }; + onFloatCallback onFloatCallback = new onFloatCallback() { + @Override + public float onFloatCallback(float floatValue01, float floatValue02) { + return internal_onFloatCallback(floatValue01, floatValue02); + } + }; + onBoolCallback onBoolCallback = new onBoolCallback() { + @Override + public boolean onBoolCallback(boolean boolValue01) { + return internal_onBoolCallback(boolValue01); + } + }; + onStringCallback onStringCallback = new onStringCallback() { + @Override + public void onStringCallback(int strValue01) { + internal_onStringCallback(IDLBase.getJSString(strValue01)); + } + }; + int pointer = createNative(onVoidCallback, onIntCallback, onFloatCallback, onBoolCallback, onStringCallback); + initNative(pointer, true); + } + */ + public CallbackClassManual() { + super((byte)0, (char)0); + long addr = createNATIVE(); + initNative(addr, true); + } + + /*[-JNI;-NATIVE] + if(CallbackClassManual_CLASS == 0) { + CallbackClassManual_CLASS = (jclass)env->NewGlobalRef(env->GetObjectClass(object)); + onVoidCallback_ID = env->GetMethodID(CallbackClassManual_CLASS, "internal_onVoidCallback", "(JJ)V"); + onIntCallback_ID = env->GetMethodID(CallbackClassManual_CLASS, "internal_onIntCallback", "(II)I"); + onFloatCallback_ID = env->GetMethodID(CallbackClassManual_CLASS, "internal_onFloatCallback", "(FF)F"); + onBoolCallback_ID = env->GetMethodID(CallbackClassManual_CLASS, "internal_onBoolCallback", "(Z)Z"); + onStringCallback_ID = env->GetMethodID(CallbackClassManual_CLASS, "internal_onStringCallback", "(Ljava/lang/String;)V"); + } + return (jlong)new CallbackClassManual(env, env->NewGlobalRef(object)); + */ + /*[-TEAVM;-REPLACE] + @org.teavm.jso.JSBody(params = { "onVoidCallback", "onIntCallback", "onFloatCallback", "onBoolCallback", "onStringCallback" }, script = "var CallbackClassImpl = new [MODULE].CallbackClassImpl(); CallbackClassImpl.onVoidCallback = onVoidCallback; CallbackClassImpl.onIntCallback = onIntCallback; CallbackClassImpl.onFloatCallback = onFloatCallback; CallbackClassImpl.onBoolCallback = onBoolCallback; CallbackClassImpl.onStringCallback = onStringCallback; return [MODULE].getPointer(CallbackClassImpl);") + private static native int createNative(onVoidCallback onVoidCallback, onIntCallback onIntCallback, onFloatCallback onFloatCallback, onBoolCallback onBoolCallback, onStringCallback onStringCallback); + */ + private native long createNATIVE(); + + public void internal_onVoidCallback(long refData, long pointerData) { + } + + public int internal_onIntCallback(int intValue01, int intValue02) { + return 0; + } + + public float internal_onFloatCallback(float floatValue01, float floatValue02) { + return 0; + } + + public boolean internal_onBoolCallback(boolean boolValue01) { + return false; + } + + public void internal_onStringCallback(String strValue01) { + } + +// private int onCall(long luaState) { +// LuaState.TMP.setPointer(luaState); +// return onCall(LuaState.TMP); +// } +// +// public int onCall(LuaState luaState) { +// return 0; +// } +} \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index f2c8124e..7f4608d0 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -172,9 +172,9 @@ interface TestCallbackClass { attribute TestObjectClass pointerObject; void callVoidCallback(CallbackClass callback); - void callIntCallback(CallbackClass callback); - void callFloatCallback(CallbackClass callback); - void callBoolCallback(CallbackClass callback); + long callIntCallback(CallbackClass callback); + float callFloatCallback(CallbackClass callback); + boolean callBoolCallback(CallbackClass callback); void callStringCallback(CallbackClass callback); }; diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h index a2a62a2e..4ef5dec1 100644 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h @@ -292,7 +292,6 @@ class DefaultCallbackClass : public CallbackClass return !boolValue01; } virtual void onStringCallback(const char* strValue01) const { - cout << "strValue01: " << strValue01 << endl; } }; @@ -314,14 +313,15 @@ class TestCallbackClass { int callIntCallback(CallbackClass* callback) { return callback->onIntCallback(intValue01, intValue02); }; - int callFloatCallback(CallbackClass* callback) { + float callFloatCallback(CallbackClass* callback) { return callback->onFloatCallback(floatValue01, floatValue02); }; bool callBoolCallback(CallbackClass* callback) { return callback->onBoolCallback(boolValue01); }; void callStringCallback(CallbackClass* callback) { - callback->onStringCallback(strValue01.c_str()); + const char* text = strValue01.c_str(); + callback->onStringCallback(text); }; }; diff --git a/jParser/base/src/main/java/idl/IDLBase.java b/jParser/base/src/main/java/idl/IDLBase.java index 36883d22..10ebf97a 100644 --- a/jParser/base/src/main/java/idl/IDLBase.java +++ b/jParser/base/src/main/java/idl/IDLBase.java @@ -41,4 +41,12 @@ public void dispose() { */ protected void deleteNative() { } + + /*[-TEAVM;-REPLACE] + @org.teavm.jso.JSBody(params = { "addr" }, script = "return [MODULE].UTF8ToString(addr);") + public static native String getJSString(int addr); + */ + public static String getJSString(long addr) { + return null; + } } \ No newline at end of file From c001ae7aaacddb5f04acf575dd836fa951ed8f74 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 22 Aug 2024 20:00:24 -0300 Subject: [PATCH 096/186] Update class name --- .../example/testlib/CallbackClassManual.java | 21 +++--------- .../lib/lib-build/src/main/cpp/TestLib.idl | 26 +++++++++++--- .../src/main/cpp/source/TestLib/src/TestLib.h | 34 +++++++++++++++++++ 3 files changed, 60 insertions(+), 21 deletions(-) diff --git a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java index 983f9e72..2bb871bb 100644 --- a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java +++ b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java @@ -1,7 +1,7 @@ package com.github.xpenatan.jparser.example.testlib; import idl.IDLBase; -public class CallbackClassManual extends CallbackClass { +public class CallbackClassManual extends IDLBase { /*[-JNI;-NATIVE] static jclass CallbackClassManual_CLASS = 0; @@ -11,12 +11,12 @@ public class CallbackClassManual extends CallbackClass { static jmethodID onBoolCallback_ID = 0; static jmethodID onStringCallback_ID = 0; - class CallbackClassManual : public CallbackClass { + class CallbackClassManual_NATIVE : public CallbackClassManual { private: JNIEnv* env; jobject obj; public: - CallbackClassManual( JNIEnv* env, jobject obj ) { + CallbackClassManual_NATIVE( JNIEnv* env, jobject obj ) { this->env = env; this->obj = obj; } @@ -72,7 +72,6 @@ public interface onStringCallback extends org.teavm.jso.JSObject { /*[-TEAVM;-REPLACE] public CallbackClassManual() { - super((byte)0, (char)0); onVoidCallback onVoidCallback = new onVoidCallback() { @Override public void onVoidCallback(int refData, int pointerData) { @@ -108,7 +107,6 @@ public void onStringCallback(int strValue01) { } */ public CallbackClassManual() { - super((byte)0, (char)0); long addr = createNATIVE(); initNative(addr, true); } @@ -122,10 +120,10 @@ public CallbackClassManual() { onBoolCallback_ID = env->GetMethodID(CallbackClassManual_CLASS, "internal_onBoolCallback", "(Z)Z"); onStringCallback_ID = env->GetMethodID(CallbackClassManual_CLASS, "internal_onStringCallback", "(Ljava/lang/String;)V"); } - return (jlong)new CallbackClassManual(env, env->NewGlobalRef(object)); + return (jlong)new CallbackClassManual_NATIVE(env, env->NewGlobalRef(object)); */ /*[-TEAVM;-REPLACE] - @org.teavm.jso.JSBody(params = { "onVoidCallback", "onIntCallback", "onFloatCallback", "onBoolCallback", "onStringCallback" }, script = "var CallbackClassImpl = new [MODULE].CallbackClassImpl(); CallbackClassImpl.onVoidCallback = onVoidCallback; CallbackClassImpl.onIntCallback = onIntCallback; CallbackClassImpl.onFloatCallback = onFloatCallback; CallbackClassImpl.onBoolCallback = onBoolCallback; CallbackClassImpl.onStringCallback = onStringCallback; return [MODULE].getPointer(CallbackClassImpl);") + @org.teavm.jso.JSBody(params = { "onVoidCallback", "onIntCallback", "onFloatCallback", "onBoolCallback", "onStringCallback" }, script = "var CallbackClassManualImpl = new [MODULE].CallbackClassManualImpl(); CallbackClassManualImpl.onVoidCallback = onVoidCallback; CallbackClassManualImpl.onIntCallback = onIntCallback; CallbackClassManualImpl.onFloatCallback = onFloatCallback; CallbackClassManualImpl.onBoolCallback = onBoolCallback; CallbackClassManualImpl.onStringCallback = onStringCallback; return [MODULE].getPointer(CallbackClassManualImpl);") private static native int createNative(onVoidCallback onVoidCallback, onIntCallback onIntCallback, onFloatCallback onFloatCallback, onBoolCallback onBoolCallback, onStringCallback onStringCallback); */ private native long createNATIVE(); @@ -147,13 +145,4 @@ public boolean internal_onBoolCallback(boolean boolValue01) { public void internal_onStringCallback(String strValue01) { } - -// private int onCall(long luaState) { -// LuaState.TMP.setPointer(luaState); -// return onCall(LuaState.TMP); -// } -// -// public int onCall(LuaState luaState) { -// return 0; -// } } \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index 7f4608d0..8a49a74c 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -134,6 +134,10 @@ interface CallbackClass { long addInt(long a, long b); }; +interface CallbackClassManual { + long addInt(long a, long b); +}; + [JSImplementation="CallbackClass"] interface CallbackClassImpl { void CallbackClassImpl(); @@ -146,6 +150,18 @@ interface CallbackClassImpl { }; CallbackClassImpl implements CallbackClass; +[JSImplementation="CallbackClassManual"] +interface CallbackClassManualImpl { + void CallbackClassManualImpl(); + + [Const] void onVoidCallback([Ref] TestObjectClass refData, TestObjectClass pointerData); + [Const] long onIntCallback(long intValue01, long intValue02); + [Const] float onFloatCallback(float floatValue01, float floatValue02); + [Const] boolean onBoolCallback(boolean boolValue01); + [Const] void onStringCallback([Const] DOMString strValue01); +}; +CallbackClassImpl implements CallbackClass; + interface DefaultCallbackClass { void DefaultCallbackClass(); }; @@ -171,11 +187,11 @@ interface TestCallbackClass { [Value] attribute TestObjectClass valueObject; attribute TestObjectClass pointerObject; - void callVoidCallback(CallbackClass callback); - long callIntCallback(CallbackClass callback); - float callFloatCallback(CallbackClass callback); - boolean callBoolCallback(CallbackClass callback); - void callStringCallback(CallbackClass callback); + void callVoidCallback(CallbackClassManual callback); + long callIntCallback(CallbackClassManual callback); + float callFloatCallback(CallbackClassManual callback); + boolean callBoolCallback(CallbackClassManual callback); + void callStringCallback(CallbackClassManual callback); }; enum TestEnumWithinClass { diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h index 4ef5dec1..bf9f147f 100644 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h @@ -270,6 +270,23 @@ class CallbackClass } }; +class CallbackClassManual +{ +public: + virtual ~CallbackClassManual() {} + + virtual void onVoidCallback(TestObjectClass& refData, TestObjectClass* pointerData) const = 0; + virtual int onIntCallback(int intValue01, int intValue02) const = 0; + virtual float onFloatCallback(float floatValue01, float Value02) const = 0; + virtual bool onBoolCallback(bool boolValue01) const = 0; + virtual void onStringCallback(const char* strValue01) const = 0; + + int addInt(int a, int b) + { + return a + b; + } +}; + class DefaultCallbackClass : public CallbackClass { public: @@ -323,6 +340,23 @@ class TestCallbackClass { const char* text = strValue01.c_str(); callback->onStringCallback(text); }; + + void callVoidCallback(CallbackClassManual* callback) { + callback->onVoidCallback(valueObject, pointerObject); + }; + int callIntCallback(CallbackClassManual* callback) { + return callback->onIntCallback(intValue01, intValue02); + }; + float callFloatCallback(CallbackClassManual* callback) { + return callback->onFloatCallback(floatValue01, floatValue02); + }; + bool callBoolCallback(CallbackClassManual* callback) { + return callback->onBoolCallback(boolValue01); + }; + void callStringCallback(CallbackClassManual* callback) { + const char* text = strValue01.c_str(); + callback->onStringCallback(text); + }; }; class TestEnumClass { From 0a27a950aba9cef3a1efd8d3c7c329805cd318c9 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 22 Aug 2024 20:08:41 -0300 Subject: [PATCH 097/186] add idl skip --- .../xpenatan/jparser/example/testlib/CallbackClassManual.java | 1 + 1 file changed, 1 insertion(+) diff --git a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java index 2bb871bb..6e276efd 100644 --- a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java +++ b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java @@ -1,6 +1,7 @@ package com.github.xpenatan.jparser.example.testlib; import idl.IDLBase; +/*[-IDL_SKIP]*/ public class CallbackClassManual extends IDLBase { /*[-JNI;-NATIVE] From c9fdbaff67f4e45b9dd7a562151ef27b0e0f583d Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 22 Aug 2024 22:14:00 -0300 Subject: [PATCH 098/186] add callback attribute --- .../github/xpenatan/jparser/idl/IDLClass.java | 2 ++ .../xpenatan/jparser/idl/IDLReader.java | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java index 5282ff01..0397cf76 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java @@ -17,6 +17,8 @@ public class IDLClass extends IDLClassOrEnum { public final ArrayList attributes = new ArrayList<>(); public ArrayList settings = new ArrayList<>(); + public IDLClass callback; + public IDLClass(IDLFile idlFile) { this.idlFile = idlFile; } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java index 8c73a510..c7732b56 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java @@ -124,6 +124,7 @@ public static IDLFile parseFile(InputStreamReader inputStreamReader, String idlN ArrayList classList = new ArrayList<>(); parseFile(idlFile, classList); idlFile.classArray.addAll(classList); + configCallbacks(idlFile, classList); } catch(Throwable t) { t.printStackTrace(); @@ -205,6 +206,30 @@ private static void parseFile(IDLFile idlFile, ArrayList classLi } } + private static void configCallbacks(IDLFile idlFile, ArrayList classList) { + for(int i = 0; i < classList.size(); i++) { + IDLClassOrEnum idlClassOrEnum = classList.get(i); + if(idlClassOrEnum.isClass()) { + IDLClass idlCallbackImpl = idlClassOrEnum.asClass(); + String jsImplementation = idlCallbackImpl.classHeader.jsImplementation; + if(jsImplementation != null) { + jsImplementation = jsImplementation.trim(); + if(!jsImplementation.isEmpty()) { + IDLClass callbackClass = idlFile.getClass(jsImplementation); + if(callbackClass != null) { + if(callbackClass.callback == null) { + callbackClass.callback = idlCallbackImpl; + } + else { + throw new RuntimeException("Class " + callbackClass.name + " cannot have multiple JSImplementation"); + } + } + } + } + } + } + } + private static String removeComment(String line) { int commentIndex = line.indexOf("//"); if(commentIndex != -1) { From f41b70b8162b1ccddb90e5f1f57d7a516643a492 Mon Sep 17 00:00:00 2001 From: Natan Date: Fri, 23 Aug 2024 20:38:06 -0300 Subject: [PATCH 099/186] Improve manual callback, add replace block and wip callback parser --- .../example/testlib/CallbackClassManual.java | 79 +++++++++++-------- .../lib/lib-build/src/main/cpp/TestLib.idl | 38 ++++----- .../core/codeparser/DefaultCodeParser.java | 20 +++-- .../xpenatan/jparser/cpp/CppCodeParser.java | 9 ++- .../github/xpenatan/jparser/idl/IDLClass.java | 1 + .../jparser/idl/parser/IDLCallbackParser.java | 13 +++ .../idl/parser/IDLClassGeneratorParser.java | 5 ++ .../idl/parser/IDLDefaultCodeParser.java | 11 +++ .../jparser/teavm/TeaVMCodeParser.java | 9 ++- 9 files changed, 124 insertions(+), 61 deletions(-) create mode 100644 jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java diff --git a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java index 6e276efd..c30cf274 100644 --- a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java +++ b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java @@ -5,37 +5,46 @@ public class CallbackClassManual extends IDLBase { /*[-JNI;-NATIVE] - static jclass CallbackClassManual_CLASS = 0; - static jmethodID onVoidCallback_ID = 0; - static jmethodID onIntCallback_ID = 0; - static jmethodID onFloatCallback_ID = 0; - static jmethodID onBoolCallback_ID = 0; - static jmethodID onStringCallback_ID = 0; - - class CallbackClassManual_NATIVE : public CallbackClassManual { + class CallbackClassManualImpl : public CallbackClassManual { private: JNIEnv* env; jobject obj; public: - CallbackClassManual_NATIVE( JNIEnv* env, jobject obj ) { + inline static jclass jClassID = 0; + inline static jmethodID onVoidCallback_ID = 0; + inline static jmethodID onIntCallback_ID = 0; + inline static jmethodID onFloatCallback_ID = 0; + inline static jmethodID onBoolCallback_ID = 0; + inline static jmethodID onStringCallback_ID = 0; + + CallbackClassManualImpl( JNIEnv* env, jobject obj ) { this->env = env; this->obj = obj; + + if(CallbackClassManualImpl::jClassID == 0) { + CallbackClassManualImpl::jClassID = (jclass)env->NewGlobalRef(env->GetObjectClass(obj)); + CallbackClassManualImpl::onVoidCallback_ID = env->GetMethodID(jClassID, "internal_onVoidCallback", "(JJ)V"); + CallbackClassManualImpl::onIntCallback_ID = env->GetMethodID(jClassID, "internal_onIntCallback", "(II)I"); + CallbackClassManualImpl::onFloatCallback_ID = env->GetMethodID(jClassID, "internal_onFloatCallback", "(FF)F"); + CallbackClassManualImpl::onBoolCallback_ID = env->GetMethodID(jClassID, "internal_onBoolCallback", "(Z)Z"); + CallbackClassManualImpl::onStringCallback_ID = env->GetMethodID(jClassID, "internal_onStringCallback", "(Ljava/lang/String;)V"); + } } virtual void onVoidCallback(TestObjectClass& refData, TestObjectClass* pointerData) const { - env->CallVoidMethod(obj, onVoidCallback_ID, (jlong)&refData, (jlong)pointerData); + env->CallVoidMethod(obj, CallbackClassManualImpl::onVoidCallback_ID, (jlong)&refData, (jlong)pointerData); } virtual int onIntCallback(int intValue01, int intValue02) const { - return env->CallIntMethod(obj, onIntCallback_ID, intValue01, intValue02); + return env->CallIntMethod(obj, CallbackClassManualImpl::onIntCallback_ID, intValue01, intValue02); } virtual float onFloatCallback(float floatValue01, float floatValue02) const { - return env->CallFloatMethod(obj, onFloatCallback_ID, floatValue01, floatValue02); + return env->CallFloatMethod(obj, CallbackClassManualImpl::onFloatCallback_ID, floatValue01, floatValue02); } virtual bool onBoolCallback(bool boolValue01) const { - return env->CallBooleanMethod(obj, onBoolCallback_ID, boolValue01); + return env->CallBooleanMethod(obj, CallbackClassManualImpl::onBoolCallback_ID, boolValue01); } virtual void onStringCallback(const char* strValue01) const { jstring jstrBuf = env->NewStringUTF(strValue01); - env->CallVoidMethod(obj, onStringCallback_ID, jstrBuf); + env->CallVoidMethod(obj, CallbackClassManualImpl::onStringCallback_ID, jstrBuf); } }; */ @@ -71,8 +80,23 @@ public interface onStringCallback extends org.teavm.jso.JSObject { } */ + public CallbackClassManual() { + long addr = internal_native_create(); + initNative(addr, true); + setCallbacks(); + } + + /*[-JNI;-NATIVE] + return (jlong)new CallbackClassManualImpl(env, env->NewGlobalRef(object)); + */ /*[-TEAVM;-REPLACE] - public CallbackClassManual() { + @org.teavm.jso.JSBody(params = { }, script = "var CallbackClassManualImpl = new [MODULE].CallbackClassManualImpl(); return [MODULE].getPointer(CallbackClassManualImpl);") + private static native int internal_native_create(); + */ + private native long internal_native_create(); + + /*[-TEAVM;-REPLACE_BLOCK] + { onVoidCallback onVoidCallback = new onVoidCallback() { @Override public void onVoidCallback(int refData, int pointerData) { @@ -103,31 +127,16 @@ public void onStringCallback(int strValue01) { internal_onStringCallback(IDLBase.getJSString(strValue01)); } }; - int pointer = createNative(onVoidCallback, onIntCallback, onFloatCallback, onBoolCallback, onStringCallback); - initNative(pointer, true); + internal_setCallbacks((int)getCPointer(), onVoidCallback, onIntCallback, onFloatCallback, onBoolCallback, onStringCallback); } */ - public CallbackClassManual() { - long addr = createNATIVE(); - initNative(addr, true); + private void setCallbacks() { } - /*[-JNI;-NATIVE] - if(CallbackClassManual_CLASS == 0) { - CallbackClassManual_CLASS = (jclass)env->NewGlobalRef(env->GetObjectClass(object)); - onVoidCallback_ID = env->GetMethodID(CallbackClassManual_CLASS, "internal_onVoidCallback", "(JJ)V"); - onIntCallback_ID = env->GetMethodID(CallbackClassManual_CLASS, "internal_onIntCallback", "(II)I"); - onFloatCallback_ID = env->GetMethodID(CallbackClassManual_CLASS, "internal_onFloatCallback", "(FF)F"); - onBoolCallback_ID = env->GetMethodID(CallbackClassManual_CLASS, "internal_onBoolCallback", "(Z)Z"); - onStringCallback_ID = env->GetMethodID(CallbackClassManual_CLASS, "internal_onStringCallback", "(Ljava/lang/String;)V"); - } - return (jlong)new CallbackClassManual_NATIVE(env, env->NewGlobalRef(object)); - */ - /*[-TEAVM;-REPLACE] - @org.teavm.jso.JSBody(params = { "onVoidCallback", "onIntCallback", "onFloatCallback", "onBoolCallback", "onStringCallback" }, script = "var CallbackClassManualImpl = new [MODULE].CallbackClassManualImpl(); CallbackClassManualImpl.onVoidCallback = onVoidCallback; CallbackClassManualImpl.onIntCallback = onIntCallback; CallbackClassManualImpl.onFloatCallback = onFloatCallback; CallbackClassManualImpl.onBoolCallback = onBoolCallback; CallbackClassManualImpl.onStringCallback = onStringCallback; return [MODULE].getPointer(CallbackClassManualImpl);") - private static native int createNative(onVoidCallback onVoidCallback, onIntCallback onIntCallback, onFloatCallback onFloatCallback, onBoolCallback onBoolCallback, onStringCallback onStringCallback); + /*[-TEAVM;-ADD] + @org.teavm.jso.JSBody(params = { "this_addr", "onVoidCallback", "onIntCallback", "onFloatCallback", "onBoolCallback", "onStringCallback" }, script = "var CallbackClassManualImpl = [MODULE].wrapPointer(this_addr, [MODULE].CallbackClassManualImpl); CallbackClassManualImpl.onVoidCallback = onVoidCallback; CallbackClassManualImpl.onIntCallback = onIntCallback; CallbackClassManualImpl.onFloatCallback = onFloatCallback; CallbackClassManualImpl.onBoolCallback = onBoolCallback; CallbackClassManualImpl.onStringCallback = onStringCallback;") + private static native void internal_setCallbacks(int this_addr, onVoidCallback onVoidCallback, onIntCallback onIntCallback, onFloatCallback onFloatCallback, onBoolCallback onBoolCallback, onStringCallback onStringCallback); */ - private native long createNATIVE(); public void internal_onVoidCallback(long refData, long pointerData) { } diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index 8a49a74c..8e939160 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -138,17 +138,17 @@ interface CallbackClassManual { long addInt(long a, long b); }; -[JSImplementation="CallbackClass"] -interface CallbackClassImpl { - void CallbackClassImpl(); - - [Const] void onVoidCallback([Ref] TestObjectClass refData, TestObjectClass pointerData); - [Const] long onIntCallback(long intValue01, long intValue02); - [Const] float onFloatCallback(float floatValue01, float floatValue02); - [Const] boolean onBoolCallback(boolean boolValue01); - [Const] void onStringCallback([Const] DOMString strValue01); -}; -CallbackClassImpl implements CallbackClass; +//[JSImplementation="CallbackClass"] +//interface CallbackClassImpl { +// void CallbackClassImpl(); +// +// [Const] void onVoidCallback([Ref] TestObjectClass refData, TestObjectClass pointerData); +// [Const] long onIntCallback(long intValue01, long intValue02); +// [Const] float onFloatCallback(float floatValue01, float floatValue02); +// [Const] boolean onBoolCallback(boolean boolValue01); +// [Const] void onStringCallback([Const] DOMString strValue01); +//}; +//CallbackClassImpl implements CallbackClass; [JSImplementation="CallbackClassManual"] interface CallbackClassManualImpl { @@ -160,20 +160,20 @@ interface CallbackClassManualImpl { [Const] boolean onBoolCallback(boolean boolValue01); [Const] void onStringCallback([Const] DOMString strValue01); }; -CallbackClassImpl implements CallbackClass; +CallbackClassManualImpl implements CallbackClassManual; interface DefaultCallbackClass { void DefaultCallbackClass(); }; DefaultCallbackClass implements CallbackClass; -[JSImplementation="DefaultCallbackClass"] -interface DefaultCallbackClassImpl { - void DefaultCallbackClassImpl(); - - [Const] long onIntCallback(long intValue01, long intValue02); -}; -DefaultCallbackClassImpl implements DefaultCallbackClass; +//[JSImplementation="DefaultCallbackClass"] +//interface DefaultCallbackClassImpl { +// void DefaultCallbackClassImpl(); +// +// [Const] long onIntCallback(long intValue01, long intValue02); +//}; +//DefaultCallbackClassImpl implements DefaultCallbackClass; interface TestCallbackClass { void TestCallbackClass(); diff --git a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/codeparser/DefaultCodeParser.java b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/codeparser/DefaultCodeParser.java index 8c3f88cb..c97ad9b9 100644 --- a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/codeparser/DefaultCodeParser.java +++ b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/codeparser/DefaultCodeParser.java @@ -10,6 +10,7 @@ import com.github.javaparser.ast.body.TypeDeclaration; import com.github.javaparser.ast.comments.BlockComment; import com.github.javaparser.ast.comments.Comment; +import com.github.javaparser.ast.stmt.BlockStmt; import com.github.xpenatan.jparser.core.JParser; import com.github.xpenatan.jparser.core.JParserItem; import com.github.xpenatan.jparser.core.util.RawCodeBlock; @@ -27,6 +28,7 @@ public abstract class DefaultCodeParser implements CodeParser { public static final String CMD_ADD_RAW = "-ADD_RAW"; public static final String CMD_REMOVE = "-REMOVE"; public static final String CMD_REPLACE = "-REPLACE"; + public static final String CMD_REPLACE_BLOCK = "-REPLACE_BLOCK"; public static final String CMD_NATIVE = "-NATIVE"; private ArrayList cache = new ArrayList<>(); @@ -163,19 +165,28 @@ private boolean parserBlock(Node node, BlockComment blockComment) { protected boolean parseCodeBlock(Node node, String headerCommands, String content) { if(headerCommands.contains(CMD_ADD_RAW)) { - setAddReplaceCMD(node, content, false, true); + setAddReplaceCMD(node, content, false, true, false); return true; } else if(headerCommands.contains(CMD_ADD)) { - setAddReplaceCMD(node, content, false, false); + setAddReplaceCMD(node, content, false, false, false); return true; } else if(headerCommands.contains(CMD_REMOVE)) { node.remove(); return true; } + else if(headerCommands.contains(CMD_REPLACE_BLOCK)) { + if(node instanceof MethodDeclaration) { + MethodDeclaration methodDeclaration = (MethodDeclaration)node; + BlockStmt blockStmt = StaticJavaParser.parseBlock(content); + methodDeclaration.setBody(blockStmt); + return true; + } + return false; + } else if(headerCommands.contains(CMD_REPLACE)) { - setAddReplaceCMD(node, content, true, false); + setAddReplaceCMD(node, content, true, false, false); return true; } else if(headerCommands.contains(CMD_NATIVE)) { @@ -190,7 +201,7 @@ else if(headerCommands.contains(CMD_NATIVE)) { return false; } - private void setAddReplaceCMD(Node node, String content, boolean replace, boolean rawAdd) { + private void setAddReplaceCMD(Node node, String content, boolean replace, boolean rawAdd, boolean replaceBlock) { Node parentNode = null; Optional parentNodeOptional = node.getParentNode(); if(parentNodeOptional.isPresent()) { @@ -211,7 +222,6 @@ private void setAddReplaceCMD(Node node, String content, boolean replace, boolea else { BodyDeclaration newCode = StaticJavaParser.parseBodyDeclaration(content); typeDeclaration.getMembers().add(newCode); - } } catch(Throwable t) { diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index 01ce33ff..c45aedd9 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -216,7 +216,14 @@ public void onIDLConstructorGenerated(JParser jParser, IDLConstructor idlConstru @Override public void onIDLDeConstructorGenerated(JParser jParser, IDLClass idlClass, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration nativeMethodDeclaration) { - String classTypeName = idlClass.classHeader.prefixName + classDeclaration.getNameAsString(); + String classTypeName; + + if(idlClass.callback == null) { + classTypeName = idlClass.classHeader.prefixName + classDeclaration.getNameAsString(); + } + else { + classTypeName = idlClass.callback.name; + } String content = METHOD_DELETE_OBJ_POINTER_TEMPLATE.replace(TEMPLATE_TAG_TYPE, classTypeName); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java index 0397cf76..2911d7db 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java @@ -18,6 +18,7 @@ public class IDLClass extends IDLClassOrEnum { public ArrayList settings = new ArrayList<>(); public IDLClass callback; + public boolean idlSkip = false; public IDLClass(IDLFile idlFile) { this.idlFile = idlFile; diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java new file mode 100644 index 00000000..c4338890 --- /dev/null +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java @@ -0,0 +1,13 @@ +package com.github.xpenatan.jparser.idl.parser; + +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.xpenatan.jparser.core.JParser; +import com.github.xpenatan.jparser.idl.IDLClass; + +public class IDLCallbackParser { + + public static void generateCallback(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classOrInterfaceDeclaration, IDLClass idlClass) { + + } +} \ No newline at end of file diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java index 58b4aa55..eabea4de 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java @@ -349,6 +349,11 @@ private void makeNativesPublic(ArrayList parserItems) { for(int i = 0; i < parserItems.size(); i++) { JParserItem parserItem = parserItems.get(i); String className = parserItem.className; + IDLClass idlClass = idlReader.getClass(className); + if(idlClass != null && idlClass.idlSkip) { + continue; + } + CompilationUnit unit = parserItem.unit; List classDeclarations = unit.findAll(ClassOrInterfaceDeclaration.class); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java index 5b1e7d5f..6e7bb29c 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java @@ -80,6 +80,7 @@ public void onParseClassStart(JParser jParser, CompilationUnit unit, ClassOrInte if(headerCommands != null) { if(headerCommands.contains(IDLDefaultCodeParser.CMD_IDL_SKIP)) { //If skip is found then remove the method + idlClass.idlSkip = true; return; } } @@ -103,6 +104,13 @@ public void onParseClassStart(JParser jParser, CompilationUnit unit, ClassOrInte IDLAttributeParser.generateAttribute(this, jParser, unit, classOrInterfaceDeclaration, idlClass, idlAttribute); } } + + if(generateClass) { + if(idlClass.callback != null) { + IDLCallbackParser.generateCallback(this, jParser, unit, classOrInterfaceDeclaration, idlClass); + } + + } } else { if(generateClass) { @@ -156,6 +164,9 @@ public void onIDLAttributeGenerated(JParser jParser, IDLAttribute idlAttribute, public void onIDLEnumMethodGenerated(JParser jParser, IDLEnum idlEnum, ClassOrInterfaceDeclaration classDeclaration, String enumStr, FieldDeclaration fieldDeclaration, MethodDeclaration nativeMethodDeclaration) { } + public void onIDLCallbackGenerated(JParser jParser, IDLClass idlClass, ClassOrInterfaceDeclaration classDeclaration) { + } + public String getIDLMethodName(String name) { return name; } diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index a9a3da6c..2d445cf1 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -301,7 +301,14 @@ public void onIDLConstructorGenerated(JParser jParser, IDLConstructor idlConstru @Override public void onIDLDeConstructorGenerated(JParser jParser, IDLClass idlClass, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration nativeMethodDeclaration) { - String returnTypeName = classDeclaration.getNameAsString(); + String returnTypeName ; + if(idlClass.callback == null) { + returnTypeName = classDeclaration.getNameAsString(); + } + else { + returnTypeName = idlClass.callback.name; + } + String content = METHOD_DELETE_OBJ_POINTER_TEMPLATE.replace(TEMPLATE_TAG_MODULE, module).replace(TEMPLATE_TAG_TYPE, returnTypeName); String header = "[-" + HEADER_CMD + ";" + CMD_NATIVE + "]"; From cbc67192260f3c8ccf3e93776df1c9384ca80b4c Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 24 Aug 2024 14:56:41 -0300 Subject: [PATCH 100/186] wip callback --- .../example/testlib/CallbackClass.java | 9 ----- .../example/testlib/CallbackClassManual.java | 33 ++++++++++++------- .../xpenatan/jparser/cpp/CppCodeParser.java | 7 ++-- .../github/xpenatan/jparser/idl/IDLClass.java | 2 +- .../xpenatan/jparser/idl/IDLConstructor.java | 6 ++-- .../jparser/idl/parser/IDLCallbackParser.java | 14 ++++++++ .../idl/parser/IDLConstructorParser.java | 23 +++++++------ .../jparser/teavm/TeaVMCodeParser.java | 6 ++-- 8 files changed, 58 insertions(+), 42 deletions(-) delete mode 100644 example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClass.java diff --git a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClass.java b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClass.java deleted file mode 100644 index 919dbd40..00000000 --- a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClass.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.github.xpenatan.jparser.example.testlib; - -import idl.IDLBase; - -public class CallbackClass extends IDLBase { - - public CallbackClass(byte b, char c) { - } -} \ No newline at end of file diff --git a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java index c30cf274..e66a23d6 100644 --- a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java +++ b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java @@ -17,9 +17,12 @@ class CallbackClassManualImpl : public CallbackClassManual { inline static jmethodID onBoolCallback_ID = 0; inline static jmethodID onStringCallback_ID = 0; - CallbackClassManualImpl( JNIEnv* env, jobject obj ) { + CallbackClassManualImpl() { + } + + void setupCallback(JNIEnv* env, jobject obj) { this->env = env; - this->obj = obj; + this->obj = env->NewGlobalRef(obj); if(CallbackClassManualImpl::jClassID == 0) { CallbackClassManualImpl::jClassID = (jclass)env->NewGlobalRef(env->GetObjectClass(obj)); @@ -83,17 +86,17 @@ public interface onStringCallback extends org.teavm.jso.JSObject { public CallbackClassManual() { long addr = internal_native_create(); initNative(addr, true); - setCallbacks(); + setupCallbacks(); } /*[-JNI;-NATIVE] - return (jlong)new CallbackClassManualImpl(env, env->NewGlobalRef(object)); + return (jlong)new CallbackClassManualImpl(); */ - /*[-TEAVM;-REPLACE] - @org.teavm.jso.JSBody(params = { }, script = "var CallbackClassManualImpl = new [MODULE].CallbackClassManualImpl(); return [MODULE].getPointer(CallbackClassManualImpl);") - private static native int internal_native_create(); + /*[-TEAVM;-NATIVE] + var CallbackClassManualImpl = new [MODULE].CallbackClassManualImpl(); + return [MODULE].getPointer(CallbackClassManualImpl); */ - private native long internal_native_create(); + private static native long internal_native_create(); /*[-TEAVM;-REPLACE_BLOCK] { @@ -127,16 +130,22 @@ public void onStringCallback(int strValue01) { internal_onStringCallback(IDLBase.getJSString(strValue01)); } }; - internal_setCallbacks((int)getCPointer(), onVoidCallback, onIntCallback, onFloatCallback, onBoolCallback, onStringCallback); + internal_native_setupCallbacks((int)getCPointer(), onVoidCallback, onIntCallback, onFloatCallback, onBoolCallback, onStringCallback); } */ - private void setCallbacks() { + private void setupCallbacks() { + internal_native_setupCallbacks(getCPointer()); } - /*[-TEAVM;-ADD] + /*[-JNI;-NATIVE] + CallbackClassManualImpl* nativeObject = (CallbackClassManualImpl*)this_addr; + nativeObject->setupCallback(env, object); + */ + /*[-TEAVM;-REPLACE] @org.teavm.jso.JSBody(params = { "this_addr", "onVoidCallback", "onIntCallback", "onFloatCallback", "onBoolCallback", "onStringCallback" }, script = "var CallbackClassManualImpl = [MODULE].wrapPointer(this_addr, [MODULE].CallbackClassManualImpl); CallbackClassManualImpl.onVoidCallback = onVoidCallback; CallbackClassManualImpl.onIntCallback = onIntCallback; CallbackClassManualImpl.onFloatCallback = onFloatCallback; CallbackClassManualImpl.onBoolCallback = onBoolCallback; CallbackClassManualImpl.onStringCallback = onStringCallback;") - private static native void internal_setCallbacks(int this_addr, onVoidCallback onVoidCallback, onIntCallback onIntCallback, onFloatCallback onFloatCallback, onBoolCallback onBoolCallback, onStringCallback onStringCallback); + private static native void internal_native_setupCallbacks(int this_addr, onVoidCallback onVoidCallback, onIntCallback onIntCallback, onFloatCallback onFloatCallback, onBoolCallback onBoolCallback, onStringCallback onStringCallback); */ + private native void internal_native_setupCallbacks(long this_addr); public void internal_onVoidCallback(long refData, long pointerData) { } diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index c45aedd9..9641a7df 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -195,12 +195,9 @@ public CppCodeParser(CppGenerator cppGenerator, IDLReader idlReader, String base @Override public void onIDLConstructorGenerated(JParser jParser, IDLConstructor idlConstructor, ClassOrInterfaceDeclaration classDeclaration, ConstructorDeclaration constructorDeclaration, MethodDeclaration nativeMethodDeclaration) { - String classTypeName = classDeclaration.getNameAsString(); + IDLClass idlClass = idlConstructor.idlClass; - IDLClass idlClass = idlConstructor.idlFile.getClass(classTypeName); - if(idlClass != null) { - classTypeName = idlClass.classHeader.prefixName + classTypeName; - } + String classTypeName = idlClass.getName(); NodeList parameters = constructorDeclaration.getParameters(); ArrayList idParameters = idlConstructor.parameters; diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java index 2911d7db..443f48a8 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java @@ -42,7 +42,7 @@ private void setAttributesAndMethods() { } else { if(line.startsWith("void " + name)) { - IDLConstructor constructor = new IDLConstructor(idlFile); + IDLConstructor constructor = new IDLConstructor(idlFile, this); constructor.initConstructor(line); constructors.add(constructor); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLConstructor.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLConstructor.java index 5c1dd017..5e9ba02d 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLConstructor.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLConstructor.java @@ -8,13 +8,15 @@ public class IDLConstructor { public final IDLFile idlFile; + public IDLClass idlClass; public String line; public String paramsLine; public final ArrayList parameters = new ArrayList<>(); - public IDLConstructor(IDLFile idlFile) { + public IDLConstructor(IDLFile idlFile, IDLClass idlClass) { this.idlFile = idlFile; + this.idlClass = idlClass; } public void initConstructor(String line) { @@ -40,7 +42,7 @@ public void removeLastParam(int count) { } public IDLConstructor clone() { - IDLConstructor cloned = new IDLConstructor(idlFile); + IDLConstructor cloned = new IDLConstructor(idlFile, idlClass); cloned.line = line; cloned.paramsLine = paramsLine; for(int i = 0; i < parameters.size(); i++) { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java index c4338890..49d185e4 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java @@ -2,12 +2,26 @@ import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.ConstructorDeclaration; +import com.github.javaparser.ast.body.MethodDeclaration; import com.github.xpenatan.jparser.core.JParser; import com.github.xpenatan.jparser.idl.IDLClass; +import com.github.xpenatan.jparser.idl.IDLConstructor; +import java.util.ArrayList; public class IDLCallbackParser { public static void generateCallback(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classOrInterfaceDeclaration, IDLClass idlClass) { + ArrayList constructors = idlClass.callback.constructors; + for(int i = 0; i < constructors.size(); i++) { + IDLConstructor idlConstructor = constructors.get(i); + ConstructorDeclaration constructorDeclaration = IDLConstructorParser.getOrCreateConstructorDeclaration(idlParser, jParser, unit, classOrInterfaceDeclaration, idlConstructor); + + if(constructorDeclaration.getBody().isEmpty()) { + MethodDeclaration nativeMethod = IDLConstructorParser.setupConstructor(idlConstructor, classOrInterfaceDeclaration, constructorDeclaration); + idlParser.onIDLConstructorGenerated(jParser, idlConstructor, classOrInterfaceDeclaration, constructorDeclaration, nativeMethod); + } + } } } \ No newline at end of file diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java index f91bec98..92b83b6b 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java @@ -28,7 +28,12 @@ public static void generateConstructor(IDLDefaultCodeParser idlParser, JParser j ArrayList constructors = idlClass.constructors; for(int i = 0; i < constructors.size(); i++) { IDLConstructor idlConstructor = constructors.get(i); - generateConstructor(idlParser, jParser, unit, classOrInterfaceDeclaration, idlConstructor); + ConstructorDeclaration constructorDeclaration = IDLConstructorParser.getOrCreateConstructorDeclaration(idlParser, jParser, unit, classOrInterfaceDeclaration, idlConstructor); + + if(constructorDeclaration.getBody().isEmpty()) { + MethodDeclaration nativeMethod = IDLConstructorParser.setupConstructor(idlConstructor, classOrInterfaceDeclaration, constructorDeclaration); + idlParser.onIDLConstructorGenerated(jParser, idlConstructor, classOrInterfaceDeclaration, constructorDeclaration, nativeMethod); + } } // All classes contain a temp constructor so temp objects can be reused @@ -70,7 +75,7 @@ private static void addSuperTempConstructor(ClassOrInterfaceDeclaration classDec } } - private static void generateConstructor(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classOrInterfaceDeclaration, IDLConstructor idlConstructor) { + public static ConstructorDeclaration getOrCreateConstructorDeclaration(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classOrInterfaceDeclaration, IDLConstructor idlConstructor) { ConstructorDeclaration constructorDeclaration = containsConstructor(classOrInterfaceDeclaration, idlConstructor); if(constructorDeclaration == null) { constructorDeclaration = classOrInterfaceDeclaration.addConstructor(Modifier.Keyword.PUBLIC); @@ -83,13 +88,10 @@ private static void generateConstructor(IDLDefaultCodeParser idlParser, JParser constructorDeclaration.addAndGetParameter(paramType, parameter.name); } } - - if(constructorDeclaration.getBody().isEmpty()) { - setupConstructor(idlParser, jParser, idlConstructor, classOrInterfaceDeclaration, constructorDeclaration); - } + return constructorDeclaration; } - private static void setupConstructor(IDLDefaultCodeParser idlParser, JParser jParser, IDLConstructor idlConstructor, ClassOrInterfaceDeclaration classDeclaration, ConstructorDeclaration constructorDeclaration) { + public static MethodDeclaration setupConstructor(IDLConstructor idlConstructor, ClassOrInterfaceDeclaration classDeclaration, ConstructorDeclaration constructorDeclaration) { NodeList parameters = constructorDeclaration.getParameters(); Type type = StaticJavaParser.parseType(classDeclaration.getNameAsString()); @@ -111,11 +113,12 @@ private static void setupConstructor(IDLDefaultCodeParser idlParser, JParser jPa blockStmt.addStatement(statement1); blockStmt.addStatement(statement2); - idlParser.onIDLConstructorGenerated(jParser, idlConstructor, classDeclaration, constructorDeclaration, nativeMethod); + return nativeMethod; } + return null; } - private static ConstructorDeclaration containsConstructor(ClassOrInterfaceDeclaration classOrInterfaceDeclaration, IDLConstructor idlConstructor) { + public static ConstructorDeclaration containsConstructor(ClassOrInterfaceDeclaration classOrInterfaceDeclaration, IDLConstructor idlConstructor) { ArrayList parameters = idlConstructor.parameters; String[] paramTypes = new String[parameters.size()]; for(int i = 0; i < parameters.size(); i++) { @@ -126,4 +129,4 @@ private static ConstructorDeclaration containsConstructor(ClassOrInterfaceDeclar Optional constructorDeclarationOptional = classOrInterfaceDeclaration.getConstructorByParameterTypes(paramTypes); return constructorDeclarationOptional.orElse(null); } -} +} \ No newline at end of file diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index 2d445cf1..bf413995 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -255,11 +255,11 @@ private void convertJavaPrimitiveArrayToJavaScriptReferenceArray(NodeList Date: Mon, 26 Aug 2024 07:59:40 -0300 Subject: [PATCH 101/186] remove constructor --- .../xpenatan/jparser/example/testlib/CallbackClassManual.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java index e66a23d6..29222a8e 100644 --- a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java +++ b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java @@ -17,9 +17,6 @@ class CallbackClassManualImpl : public CallbackClassManual { inline static jmethodID onBoolCallback_ID = 0; inline static jmethodID onStringCallback_ID = 0; - CallbackClassManualImpl() { - } - void setupCallback(JNIEnv* env, jobject obj) { this->env = env; this->obj = env->NewGlobalRef(obj); From 0475a7bf628947492f5586e9a26fe1eb45c5863e Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 26 Aug 2024 08:20:53 -0300 Subject: [PATCH 102/186] remove forced cast to long --- .../xpenatan/jparser/idl/parser/IDLDeConstructorParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java index ed0c976a..3abb3141 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java @@ -45,7 +45,7 @@ else if(size == 0) { if(!JParserHelper.containsMethod(classOrInterfaceDeclaration, nativeMethod)) { classOrInterfaceDeclaration.getMembers().add(nativeMethod); MethodCallExpr caller = IDLMethodParser.createCaller(nativeMethod); - caller.addArgument("(long)" + IDLDefaultCodeParser.CPOINTER_METHOD); + caller.addArgument(IDLDefaultCodeParser.CPOINTER_METHOD); BlockStmt blockStmt = deleteMethod.getBody().get(); blockStmt.addStatement(caller); idlParser.onIDLDeConstructorGenerated(jParser, idlClass, classOrInterfaceDeclaration, nativeMethod); From 5dc9000303ce085eda8133cf74d5a0752a6b5497 Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 26 Aug 2024 09:04:09 -0300 Subject: [PATCH 103/186] Revert removing long so its possible to generate public native method --- .../xpenatan/jparser/idl/parser/IDLDeConstructorParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java index 3abb3141..ed0c976a 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java @@ -45,7 +45,7 @@ else if(size == 0) { if(!JParserHelper.containsMethod(classOrInterfaceDeclaration, nativeMethod)) { classOrInterfaceDeclaration.getMembers().add(nativeMethod); MethodCallExpr caller = IDLMethodParser.createCaller(nativeMethod); - caller.addArgument(IDLDefaultCodeParser.CPOINTER_METHOD); + caller.addArgument("(long)" + IDLDefaultCodeParser.CPOINTER_METHOD); BlockStmt blockStmt = deleteMethod.getBody().get(); blockStmt.addStatement(caller); idlParser.onIDLDeConstructorGenerated(jParser, idlClass, classOrInterfaceDeclaration, nativeMethod); From e83190ba520314e6e08c0879c10ab5f76bb7ac84 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 29 Aug 2024 21:57:11 -0300 Subject: [PATCH 104/186] Parse cpp callbacks --- .../xpenatan/jparser/example/app/AppTest.java | 2 +- .../xpenatan/jparser/example/app/TestLib.java | 165 ++++++++++++- .../lib/lib-build/src/main/cpp/TestLib.idl | 50 ++-- .../src/main/cpp/source/TestLib/src/TestLib.h | 26 +- .../xpenatan/jparser/core/JParserHelper.java | 4 + .../xpenatan/jparser/cpp/CppCodeParser.java | 227 +++++++++++++++++- .../jparser/cpp/JNITypeSignature.java | 31 +++ .../xpenatan/jparser/idl/IDLMethod.java | 18 +- .../xpenatan/jparser/idl/IDLParameter.java | 25 +- .../jparser/idl/parser/IDLCallbackParser.java | 94 +++++++- .../idl/parser/IDLConstructorParser.java | 2 +- .../idl/parser/IDLDeConstructorParser.java | 2 +- .../idl/parser/IDLDefaultCodeParser.java | 5 +- .../jparser/idl/parser/IDLMethodParser.java | 36 ++- .../jparser/teavm/TeaVMCodeParser.java | 2 +- 15 files changed, 617 insertions(+), 72 deletions(-) create mode 100644 jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/JNITypeSignature.java diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java index 5fb26613..6b2f6121 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java @@ -39,7 +39,7 @@ public void render() { if(init) { init = false; testPass = TestLib.test(); - color = testPass ? Color.GREEN : Color.RED; + color = testPass ? Color.LIME : Color.RED; return; } diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java index cfef0fe3..352dd02f 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java @@ -1,5 +1,6 @@ package com.github.xpenatan.jparser.example.app; +import com.github.xpenatan.jparser.example.testlib.CallbackClass; import com.github.xpenatan.jparser.example.testlib.CallbackClassManual; import com.github.xpenatan.jparser.example.testlib.TestCallbackClass; import com.github.xpenatan.jparser.example.testlib.TestConstructorClass; @@ -254,6 +255,160 @@ private static boolean testStaticMethodClass() { } private static boolean testCallbackClass() { + { + TestCallbackClass test = new TestCallbackClass(); + try { + boolean[] internal_onVoidCallback = { false }; + CallbackClass callback = new CallbackClass() { + @Override + public void onVoidCallback(TestObjectClass refData, TestObjectClass pointerData) { + internal_onVoidCallback[0] = true; + } + }; + test.callVoidCallback(callback); + if(!(internal_onVoidCallback[0] == true)) { + throw new RuntimeException("internal_onVoidCallback[0] == true"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } + { + TestCallbackClass test = new TestCallbackClass(); + try { + boolean[] internal_onIntCallback = { false }; + CallbackClass callback = new CallbackClass() { + @Override + public int onIntCallback(int intValue01, int intValue02) { + internal_onIntCallback[0] = true; + return 0; + } + }; + test.callIntCallback(callback); + if(!(internal_onIntCallback[0] == true)) { + throw new RuntimeException("internal_onIntCallback[0] == true"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } + { + TestCallbackClass test = new TestCallbackClass(); + try { + boolean[] internal_onFloatCallback = { false }; + CallbackClass callback = new CallbackClass() { + @Override + public float onFloatCallback(float floatValue01, float floatValue02) { + internal_onFloatCallback[0] = true; + return 0; + } + }; + test.callFloatCallback(callback); + if(!(internal_onFloatCallback[0] == true)) { + throw new RuntimeException("internal_onFloatCallback[0] == true"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } + { + TestCallbackClass test = new TestCallbackClass(); + try { + boolean[] internal_onBoolCallback = { false }; + CallbackClass callback = new CallbackClass() { + @Override + public boolean onBoolCallback(boolean boolValue01) { + internal_onBoolCallback[0] = true; + return false; + } + }; + test.callBoolCallback(callback); + if(!(internal_onBoolCallback[0] == true)) { + throw new RuntimeException("internal_onBoolCallback[0] == true"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } + { + TestCallbackClass test = new TestCallbackClass(); + try { + String text = "HELLO_WORLD"; + test.get_strValue01().append(text); + final String[] internal_onStringCallback = new String[1]; + CallbackClass callback = new CallbackClass() { + @Override + public void onStringCallback(String strValue01) { + internal_onStringCallback[0] = strValue01; + } + }; + test.callStringCallback(callback); + if(!(text.equals(internal_onStringCallback[0]) == true)) { + throw new RuntimeException("text.equals(internal_onStringCallback[0]) == true"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } + { + TestCallbackClass test = new TestCallbackClass(); + try { + int[] onUnsignedIntCallback = { 0 }; + CallbackClass callback = new CallbackClass() { + @Override + public int onUnsignedIntCallback(int unsignedInt) { + onUnsignedIntCallback[0] = unsignedInt; + return 2; + } + }; + int i = test.callUnsignedIntCallback(callback); + if(!(onUnsignedIntCallback[0] == 13 && i == 2)) { + throw new RuntimeException("onUnsignedIntCallback[0] == 13 && i == 2"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } + { + TestCallbackClass test = new TestCallbackClass(); + try { + short[] onUnsignedShortCallback = { 0 }; + CallbackClass callback = new CallbackClass() { + @Override + public short onUnsignedShortCallback(short unsignedShort) { + onUnsignedShortCallback[0] = unsignedShort; + return 3; + } + }; + short i = test.callUnsignedShortCallback(callback); + if(!(onUnsignedShortCallback[0] == 12 && i == 3)) { + throw new RuntimeException("onUnsignedShortCallback[0] == 12 && i == 3"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } return true; } @@ -269,7 +424,7 @@ public void internal_onVoidCallback(long refData, long pointerData) { internal_onVoidCallback[0] = true; } }; - test.callVoidCallback(callback); + test.callManualVoidCallback(callback); if(!(internal_onVoidCallback[0] == true)) { throw new RuntimeException("internal_onVoidCallback[0] == true"); } @@ -291,7 +446,7 @@ public int internal_onIntCallback(int intValue01, int intValue02) { return 0; } }; - test.callIntCallback(callback); + test.callManualIntCallback(callback); if(!(internal_onIntCallback[0] == true)) { throw new RuntimeException("internal_onIntCallback[0] == true"); } @@ -313,7 +468,7 @@ public float internal_onFloatCallback(float floatValue01, float floatValue02) { return 0; } }; - test.callFloatCallback(callback); + test.callManualFloatCallback(callback); if(!(internal_onFloatCallback[0] == true)) { throw new RuntimeException("internal_onFloatCallback[0] == true"); } @@ -335,7 +490,7 @@ public boolean internal_onBoolCallback(boolean boolValue01) { return false; } }; - test.callBoolCallback(callback); + test.callManualBoolCallback(callback); if(!(internal_onBoolCallback[0] == true)) { throw new RuntimeException("internal_onBoolCallback[0] == true"); } @@ -358,7 +513,7 @@ public void internal_onStringCallback(String strValue01) { internal_onStringCallback[0] = strValue01; } }; - test.callStringCallback(callback); + test.callManualStringCallback(callback); if(!(text.equals(internal_onStringCallback[0]) == true)) { throw new RuntimeException("text.equals(internal_onStringCallback[0]) == true"); } diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index 8e939160..190a69fd 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -138,17 +138,19 @@ interface CallbackClassManual { long addInt(long a, long b); }; -//[JSImplementation="CallbackClass"] -//interface CallbackClassImpl { -// void CallbackClassImpl(); -// -// [Const] void onVoidCallback([Ref] TestObjectClass refData, TestObjectClass pointerData); -// [Const] long onIntCallback(long intValue01, long intValue02); -// [Const] float onFloatCallback(float floatValue01, float floatValue02); -// [Const] boolean onBoolCallback(boolean boolValue01); -// [Const] void onStringCallback([Const] DOMString strValue01); -//}; -//CallbackClassImpl implements CallbackClass; +[JSImplementation="CallbackClass"] +interface CallbackClassImpl { + void CallbackClassImpl(); + + [Const] void onVoidCallback([Ref] TestObjectClass refData, TestObjectClass pointerData); + [Const] long onIntCallback(long intValue01, long intValue02); + [Const] float onFloatCallback(float floatValue01, float floatValue02); + [Const] boolean onBoolCallback(boolean boolValue01); + [Const] void onStringCallback([Const] DOMString strValue01); + unsigned long onUnsignedIntCallback(unsigned long unsignedInt); + [Const] unsigned short onUnsignedShortCallback(unsigned short unsignedShort); +}; +CallbackClassImpl implements CallbackClass; [JSImplementation="CallbackClassManual"] interface CallbackClassManualImpl { @@ -162,10 +164,10 @@ interface CallbackClassManualImpl { }; CallbackClassManualImpl implements CallbackClassManual; -interface DefaultCallbackClass { - void DefaultCallbackClass(); -}; -DefaultCallbackClass implements CallbackClass; +//interface DefaultCallbackClass { +// void DefaultCallbackClass(); +//}; +//DefaultCallbackClass implements CallbackClass; //[JSImplementation="DefaultCallbackClass"] //interface DefaultCallbackClassImpl { @@ -187,11 +189,19 @@ interface TestCallbackClass { [Value] attribute TestObjectClass valueObject; attribute TestObjectClass pointerObject; - void callVoidCallback(CallbackClassManual callback); - long callIntCallback(CallbackClassManual callback); - float callFloatCallback(CallbackClassManual callback); - boolean callBoolCallback(CallbackClassManual callback); - void callStringCallback(CallbackClassManual callback); + void callVoidCallback(CallbackClass callback); + long callIntCallback(CallbackClass callback); + float callFloatCallback(CallbackClass callback); + boolean callBoolCallback(CallbackClass callback); + void callStringCallback(CallbackClass callback); + unsigned long callUnsignedIntCallback(CallbackClass callback); + unsigned short callUnsignedShortCallback(CallbackClass callback); + + void callManualVoidCallback(CallbackClassManual callback); + long callManualIntCallback(CallbackClassManual callback); + float callManualFloatCallback(CallbackClassManual callback); + boolean callManualBoolCallback(CallbackClassManual callback); + void callManualStringCallback(CallbackClassManual callback); }; enum TestEnumWithinClass { diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h index bf9f147f..89964d17 100644 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h @@ -263,6 +263,8 @@ class CallbackClass virtual float onFloatCallback(float floatValue01, float Value02) const = 0; virtual bool onBoolCallback(bool boolValue01) const = 0; virtual void onStringCallback(const char* strValue01) const = 0; + virtual unsigned int onUnsignedIntCallback(unsigned int unsignedInt) = 0; + virtual unsigned short onUnsignedShortCallback(unsigned short unsignedShort) const = 0; int addInt(int a, int b) { @@ -310,6 +312,12 @@ class DefaultCallbackClass : public CallbackClass } virtual void onStringCallback(const char* strValue01) const { } + virtual unsigned int onUnsignedIntCallback(unsigned int unsignedInt) { + return 10; + } + virtual unsigned short onUnsignedShortCallback(unsigned short unsignedShort) const { + return 20; + } }; class TestCallbackClass { @@ -340,20 +348,28 @@ class TestCallbackClass { const char* text = strValue01.c_str(); callback->onStringCallback(text); }; + unsigned int callUnsignedIntCallback(CallbackClass* callback) { + unsigned int value = 13; + return callback->onUnsignedIntCallback(value); + }; + unsigned short callUnsignedShortCallback(CallbackClass* callback) { + unsigned short value = 12; + return callback->onUnsignedShortCallback(value); + }; - void callVoidCallback(CallbackClassManual* callback) { + void callManualVoidCallback(CallbackClassManual* callback) { callback->onVoidCallback(valueObject, pointerObject); }; - int callIntCallback(CallbackClassManual* callback) { + int callManualIntCallback(CallbackClassManual* callback) { return callback->onIntCallback(intValue01, intValue02); }; - float callFloatCallback(CallbackClassManual* callback) { + float callManualFloatCallback(CallbackClassManual* callback) { return callback->onFloatCallback(floatValue01, floatValue02); }; - bool callBoolCallback(CallbackClassManual* callback) { + bool callManualBoolCallback(CallbackClassManual* callback) { return callback->onBoolCallback(boolValue01); }; - void callStringCallback(CallbackClassManual* callback) { + void callManualStringCallback(CallbackClassManual* callback) { const char* text = strValue01.c_str(); callback->onStringCallback(text); }; diff --git a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParserHelper.java b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParserHelper.java index 80887c29..7d17a3df 100644 --- a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParserHelper.java +++ b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParserHelper.java @@ -41,6 +41,10 @@ public static boolean isInt(Type type) { return JParserHelper.isType(type, "int"); } + public static boolean isShort(Type type) { + return JParserHelper.isType(type, "short"); + } + public static boolean isFloat(Type type) { return JParserHelper.isType(type, "float"); } diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index 9641a7df..0bbf2f15 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -1,6 +1,7 @@ package com.github.xpenatan.jparser.cpp; import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.Modifier; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; @@ -8,8 +9,14 @@ import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.Parameter; +import com.github.javaparser.ast.comments.BlockComment; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.stmt.BlockStmt; +import com.github.javaparser.ast.type.PrimitiveType; import com.github.javaparser.ast.type.Type; +import com.github.javaparser.utils.Pair; import com.github.xpenatan.jparser.core.JParser; +import com.github.xpenatan.jparser.core.JParserHelper; import com.github.xpenatan.jparser.core.JParserItem; import com.github.xpenatan.jparser.idl.IDLAttribute; import com.github.xpenatan.jparser.idl.IDLConstructor; @@ -23,6 +30,7 @@ import com.github.xpenatan.jparser.idl.IDLParameter; import com.github.xpenatan.jparser.idl.IDLReader; import com.github.xpenatan.jparser.idl.parser.IDLMethodOperation; +import com.github.xpenatan.jparser.idl.parser.IDLMethodParser; import java.util.ArrayList; public class CppCodeParser extends IDLDefaultCodeParser { @@ -386,9 +394,226 @@ public void onIDLEnumMethodGenerated(JParser jParser, IDLEnum idlEnum, ClassOrIn nativeMethodDeclaration.setBlockComment(blockComment); } + @Override + public void onIDLCallbackGenerated(JParser jParser, IDLClass idlClass, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration callbackDeclaration, ArrayList>> methods) { + NodeList methodParameters = callbackDeclaration.getParameters(); + IDLClass idlCallbackClass = idlClass.callback; + Type methodReturnType = callbackDeclaration.getType(); + MethodDeclaration nativeMethodDeclaration = IDLMethodParser.generateNativeMethod(callbackDeclaration.getNameAsString(), methodParameters, methodReturnType, false); + if(!JParserHelper.containsMethod(classDeclaration, nativeMethodDeclaration)) { + nativeMethodDeclaration.removeModifier(Modifier.Keyword.STATIC); + + // Call setupMethod + classDeclaration.getMembers().add(nativeMethodDeclaration); + MethodCallExpr caller = IDLMethodParser.createCaller(nativeMethodDeclaration); + caller.addArgument(IDLDefaultCodeParser.CPOINTER_METHOD); + BlockStmt blockStmt = callbackDeclaration.getBody().get(); + blockStmt.addStatement(caller); + String method = callbackDeclaration.getNameAsString() + "(env, object)"; + String content = METHOD_CALL_VOID_TEMPLATE.replace(TEMPLATE_TAG_METHOD, method).replace(TEMPLATE_TAG_TYPE, idlCallbackClass.name); + String header = "[-" + HEADER_CMD + ";" + CMD_NATIVE + "]"; + String blockComment = header + content; + nativeMethodDeclaration.setBlockComment(blockComment); + + + generateCPPClass(idlClass, classDeclaration, callbackDeclaration, methods); + } + } + + + private void generateCPPClass(IDLClass idlClass, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration callbackDeclaration, ArrayList>> methods) { + IDLClass callback = idlClass.callback; + String cppClass = ""; + + String callbackCode = generateSetupCallbackMethod(idlClass, callbackDeclaration, methods); + String methodsCode = generateMethodCallers(idlClass, methods); + cppClass += "" + + "class " + callback.name + " : public " + idlClass.name + " {\n" + + "private:\n" + + "\tJNIEnv* env;\n" + + "\tjobject obj;\n" + + "public:\n"; + cppClass += callbackCode; + cppClass += methodsCode; + cppClass += "};\n"; + + String header = "[-" + HEADER_CMD + ";" + CMD_NATIVE + "]\n"; + String code = header + cppClass; + + classDeclaration.getConstructors().get(0).setBlockComment(code); + + System.out.println(); + } + + private String generateSetupCallbackMethod(IDLClass idlClass, MethodDeclaration callbackDeclaration, ArrayList>> methods) { + String contentTemplate = "" + + "\tinline static jclass jClassID = 0;\n" + + "[VARIABLES]\n" + + "void [METHOD](JNIEnv* env, jobject obj) {\n" + + "\tthis->env = env;\n" + + "\tthis->obj = env->NewGlobalRef(obj);\n" + + "\tif([CLASS_NAME]::jClassID == 0) {\n" + + "\t\t[CLASS_NAME]::jClassID = (jclass)env->NewGlobalRef(env->GetObjectClass(obj));\n" + + "[METHOD_IDS]" + + "\t}\n" + + "}\n"; + String variableTemplate = "\tinline static jmethodID [METHOD]_ID = 0;\n"; + String methodIdTemplate = "\t\t[CLASS_NAME]::[METHOD]_ID = env->GetMethodID(jClassID, \"[INTERNAL_METHOD]\", \"[PARAM_CODE]\");\n"; + + IDLClass callbackClass = idlClass.callback; + String className = callbackClass.name; + + String staticVariables = ""; + String methodIds = ""; + String methodName = callbackDeclaration.getNameAsString(); + + for(int i = 0; i < methods.size(); i++) { + Pair> pair = methods.get(i); + IDLMethod idlMethod = pair.a; + Pair methodPair = pair.b; + MethodDeclaration internalMethod = methodPair.a; + MethodDeclaration publicMethod = methodPair.b; + String internalMethodName = internalMethod.getNameAsString(); + String paramCode = ""; + + Type returnType = internalMethod.getType(); + String returnTypeStr = returnType.asString(); + + NodeList parameters = internalMethod.getParameters(); + for(int i1 = 0; i1 < parameters.size(); i1++) { + Parameter parameter = parameters.get(i1); + Type type = parameter.getType(); + String typeStr = type.asString(); + if(type.isPrimitiveType()) { + String jniType = JNITypeSignature.getJNIType(typeStr); + paramCode += jniType; + } + else if(type.isClassOrInterfaceType()) { + if(typeStr.equals("String")) { + paramCode += JNITypeSignature.String.getJNIType(); + } + } + } + + paramCode = "(" + paramCode + ")" + JNITypeSignature.getJNIType(returnTypeStr); + + String variable = variableTemplate.replace("[METHOD]", idlMethod.name); + String methodId = methodIdTemplate.replace("[METHOD]", idlMethod.name) + .replace("[CLASS_NAME]", className) + .replace("[INTERNAL_METHOD]", internalMethodName) + .replace("[PARAM_CODE]", paramCode); + staticVariables += variable; + methodIds += methodId; + } + + String content = contentTemplate.replace("[VARIABLES]", staticVariables) + .replace("[METHOD]", methodName) + .replace("[CLASS_NAME]", className) + .replace("[METHOD_IDS]", methodIds); + + return content; + } + + private String generateMethodCallers(IDLClass idlClass, ArrayList>> methods) { + IDLClass callback = idlClass.callback; + String cppMethods = ""; + String cppClassName = callback.name; + + String methodTemplate = "" + + "virtual [RETURN_TYPE] [METHOD]([PARAMS])[CONST] {\n" + + " [RETURN]env->[CALL_METHOD](obj, [CPP_CLASS]::[METHOD]_ID[CALL_PARAMS]);\n" + + "}\n"; + + for(int i = 0; i < methods.size(); i++) { + Pair> pair = methods.get(i); + IDLMethod idlMethod = pair.a; + Pair methodPair = pair.b; + MethodDeclaration internalMethod = methodPair.a; + MethodDeclaration publicMethod = methodPair.b; + + Type type = internalMethod.getType(); + boolean isVoidType = type.isVoidType(); + String typeStr = getCPPType(idlMethod.returnType); + + String methodName = idlMethod.name; + String methodParams = ""; + String callParams = ""; + String constStr = idlMethod.isReturnConst ? " const" : ""; + + NodeList publicMethodParameters = publicMethod.getParameters(); + for(int i1 = 0; i1 < idlMethod.parameters.size(); i1++) { + IDLParameter idlParameter = idlMethod.parameters.get(i1); + Parameter parameter = publicMethodParameters.get(i1); + boolean isPrimitive = parameter.getType().isPrimitiveType(); + String paramName = idlParameter.name; + String callParamName = idlParameter.name; + String paramType = idlParameter.type; + boolean isString = paramType.equals("String"); + String tag = " "; + String callParamCast = ""; + + if(!isString) { + if(idlParameter.isRef) { + tag = "& "; + callParamCast = "(jlong)&"; + } + else if(!isPrimitive && !idlParameter.isValue) { + tag = "* "; + callParamCast = "(jlong)"; + } + } + else { + callParamName = "env->NewStringUTF(" + paramName + ")"; + } + paramType = getCPPType(paramType); + if(idlParameter.isConst) { + paramType = "const " + paramType; + } + callParams += ", "; + callParams += callParamCast + callParamName; + + methodParams += paramType + tag + paramName; + if(i1 < idlMethod.parameters.size() - 1) { + methodParams += ", "; + } + } + + String returnStr = ""; + if(!isVoidType) { + returnStr = "return "; + } + + if(typeStr.contains("unsigned")) { + returnStr += "(" + typeStr + ")"; + } + String callMethod = getCPPCallMethod(type); + String methodStr = methodTemplate.replace("[CALL_METHOD]", callMethod).replace("[CPP_CLASS]", cppClassName).replace("[METHOD]", methodName).replace("[CALL_PARAMS]", callParams).replace("[RETURN]", returnStr); + methodStr = methodStr.replace("[RETURN_TYPE]", typeStr).replace("[METHOD]", methodName).replace("[PARAMS]", methodParams).replace("[CONST]", constStr); + + cppMethods += methodStr; + } + return cppMethods; + } + + private String getCPPCallMethod(Type type) { + String typeString = type.asString(); + typeString = typeString.substring(0, 1).toUpperCase() + typeString.substring(1); + return "Call" + typeString + "Method"; + } + + private String getCPPType(String typeString) { + if(typeString.equals("boolean")) { + return "bool"; + } + if(typeString.equals("String")) { + return "char*"; + } + return typeString; + } + private void setupMethodGenerated(IDLMethod idlMethod, String param, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, MethodDeclaration nativeMethod) { Type returnType = methodDeclaration.getType(); - String returnTypeStr = idlMethod.returnType; + String returnTypeStr = idlMethod.getReturnType(); String methodName = idlMethod.name; String classTypeName = classDeclaration.getNameAsString(); IDLClass idlClass = idlMethod.idlFile.getClass(classTypeName); diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/JNITypeSignature.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/JNITypeSignature.java new file mode 100644 index 00000000..d9a983c8 --- /dev/null +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/JNITypeSignature.java @@ -0,0 +1,31 @@ +package com.github.xpenatan.jparser.cpp; + +public enum JNITypeSignature { + Void("V"), Boolean("Z"), Byte("B"), Char("C"), Short("S"), Int("I"), Long("J"), Float("F"), Double("D"), String("Ljava/lang/String;"); + + private final String jniType; + + JNITypeSignature(String type) { + jniType = type; + } + + String getJNIType() { + return jniType; + } + + static String getJNIType(String type) { + JNITypeSignature[] values = JNITypeSignature.values(); + for(int i = 0; i < values.length; i++) { + JNITypeSignature value = values[i]; + if(value.name().toLowerCase().equals(type)) { + return value.getJNIType(); + } + } + return null; + } + + static String getJNIObject(String classpath) { + classpath = classpath.replace(".", "/"); + return "L"+ classpath + ";"; + } +} \ No newline at end of file diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java index 87968ce7..ebd6d874 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java @@ -34,13 +34,14 @@ public void initMethod(String line) { paramsLine = IDLMethod.setParameters(idlFile, line, parameters); int index = line.indexOf("("); String leftSide = line.substring(0, index).trim(); + leftSide = IDLHelper.removeMultipleSpaces(leftSide.trim()); String tagsStr = IDLHelper.getTags(leftSide); if(!tagsStr.isEmpty()) { isReturnRef = tagsStr.contains("Ref"); isReturnValue = tagsStr.contains("Value"); isReturnConst = tagsStr.contains("Const"); - leftSide = leftSide.replace(tagsStr, ""); + leftSide = leftSide.replace(tagsStr, "").trim(); tagsStr = tagsStr.substring(1, tagsStr.length()-1); for(String s : tagsStr.split(",")) { @@ -53,21 +54,22 @@ public void initMethod(String line) { } if(leftSide.contains("[]")) { - leftSide = leftSide.replace("[]", ""); + leftSide = leftSide.replace("[]", "").trim(); isReturnArray = true; } - leftSide = IDLHelper.removeMultipleSpaces(leftSide.trim()); if(leftSide.contains("static")) { + leftSide = leftSide.replace("static", "").trim(); isStaticMethod = true; } String[] s = leftSide.split(" "); name = s[s.length-1]; - returnType = s[s.length-2]; + leftSide = leftSide.replace(name, "").trim(); + returnType = leftSide; - if(returnType.equals("long")) { - returnType = "int"; + if(returnType.contains("long")) { + returnType = returnType.replace("long", "int"); } if(returnType.equals("DOMString")) { returnType = "String"; @@ -79,6 +81,10 @@ public void initMethod(String line) { } } + public String getReturnType() { + return returnType.replace("unsigned", "").trim(); + } + public int getTotalOptionalParams() { int count = 0; for(int i = 0; i < parameters.size(); i++) { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java index 5c62de24..2e7871b1 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java @@ -31,11 +31,13 @@ public void initParameter(String line) { optional = line.contains("optional"); isArray = line.contains("[]"); + tmpLine = tmpLine.replace("optional", "").trim(); + tmpLine = tmpLine.replace("[]", "").trim(); - int startIndex = line.indexOf("["); - int endIndex = line.indexOf("]"); + int startIndex = tmpLine.indexOf("["); + int endIndex = tmpLine.indexOf("]"); if(startIndex != -1 && endIndex != -1 && startIndex + 2 < endIndex) { - String tagsStr = line.substring(startIndex, endIndex + 1); + String tagsStr = tmpLine.substring(startIndex, endIndex + 1); isRef = tagsStr.contains("Ref"); isConst = tagsStr.contains("Const"); isValue = tagsStr.contains("Value"); @@ -53,15 +55,18 @@ public void initParameter(String line) { } String[] s1 = tmpLine.split(" "); - type = s1[s1.length - 2]; + name = s1[s1.length - 1]; + tmpLine = tmpLine.replace(name, "").trim(); + + type = tmpLine; if(isArray) { type = type + "[]"; } - if(type.equals("long")) { + if(type.contains("long")) { // long in webidl means int - type = "int"; + type = type.replace("long", "int"); } if(type.equals("any") || type.equals("VoidPtr")) { @@ -69,9 +74,6 @@ public void initParameter(String line) { isAny = true; } - if(type.equals("long[]")) { - type = "int[]"; - } if(type.equals("DOMString")) { type = "String"; } @@ -95,10 +97,13 @@ else if(type.equals("boolean[]")) { else if(type.equals("double[]")) { type = "IDLDoubleArray"; } + } - name = s1[s1.length - 1]; + public String getType() { + return type.replace("unsigned", "").trim(); } + public IDLParameter clone() { IDLParameter clonedParam = new IDLParameter(idlFile); clonedParam.line = line; diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java index 49d185e4..5f443048 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java @@ -1,27 +1,109 @@ package com.github.xpenatan.jparser.idl.parser; +import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.Modifier; +import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.ConstructorDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.body.Parameter; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.stmt.BlockStmt; +import com.github.javaparser.ast.stmt.ReturnStmt; +import com.github.javaparser.ast.type.PrimitiveType; +import com.github.javaparser.ast.type.Type; +import com.github.javaparser.utils.Pair; import com.github.xpenatan.jparser.core.JParser; import com.github.xpenatan.jparser.idl.IDLClass; import com.github.xpenatan.jparser.idl.IDLConstructor; +import com.github.xpenatan.jparser.idl.IDLMethod; import java.util.ArrayList; public class IDLCallbackParser { - public static void generateCallback(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classOrInterfaceDeclaration, IDLClass idlClass) { + private final static String callbackMethodName = "setupCallback"; + + public static void generateCallback(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classDeclaration, IDLClass idlClass) { + ArrayList constructors = idlClass.callback.constructors; - for(int i = 0; i < constructors.size(); i++) { - IDLConstructor idlConstructor = constructors.get(i); - ConstructorDeclaration constructorDeclaration = IDLConstructorParser.getOrCreateConstructorDeclaration(idlParser, jParser, unit, classOrInterfaceDeclaration, idlConstructor); + if(constructors.size() == 1) { + IDLConstructor idlConstructor = constructors.get(0); + ConstructorDeclaration constructorDeclaration = IDLConstructorParser.getOrCreateConstructorDeclaration(idlParser, jParser, unit, classDeclaration, idlConstructor); if(constructorDeclaration.getBody().isEmpty()) { - MethodDeclaration nativeMethod = IDLConstructorParser.setupConstructor(idlConstructor, classOrInterfaceDeclaration, constructorDeclaration); - idlParser.onIDLConstructorGenerated(jParser, idlConstructor, classOrInterfaceDeclaration, constructorDeclaration, nativeMethod); + MethodDeclaration callbackSetupDeclaration = classDeclaration.addMethod(callbackMethodName, Modifier.Keyword.PRIVATE); + ArrayList>> methods = createCallbackMethods(idlParser, jParser, unit, classDeclaration, idlClass); + MethodDeclaration nativeMethod = IDLConstructorParser.setupConstructor(idlConstructor, classDeclaration, constructorDeclaration); + idlParser.onIDLConstructorGenerated(jParser, idlConstructor, classDeclaration, constructorDeclaration, nativeMethod); + MethodCallExpr caller = IDLMethodParser.createCaller(callbackSetupDeclaration); + constructorDeclaration.getBody().addStatement(caller); + idlParser.onIDLCallbackGenerated(jParser, idlClass, classDeclaration, callbackSetupDeclaration, methods); + } + } + else { + throw new RuntimeException("Callback need to have 1 constructor"); + } + } + + + private static ArrayList>> createCallbackMethods(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classDeclaration, IDLClass idlClass) { + ArrayList>> methods = new ArrayList<>(); + IDLClass callbackClass = idlClass.callback; + + for(IDLMethod method : callbackClass.methods) { + MethodDeclaration methodDeclaration = IDLMethodParser.generateAndAddMethodOnly(idlParser, jParser, unit, classDeclaration, method); + MethodDeclaration internalMethod = methodDeclaration.clone(); + + internalMethod.removeModifier(Modifier.Keyword.PUBLIC); + internalMethod.addModifier(Modifier.Keyword.PRIVATE); + + NodeList parameters = internalMethod.getParameters(); + + MethodCallExpr caller = IDLMethodParser.createCaller(methodDeclaration); + + String createFieldObjectCode = ""; + for(int i = 0; i < parameters.size(); i++) { + Parameter parameter = parameters.get(i); + String paramName = parameter.getNameAsString(); + Type type = parameter.getType(); + String typeStr = type.asString(); + String fieldName = paramName; + + if(type.isClassOrInterfaceType() && !typeStr.equals("String")) { + parameter.setType(PrimitiveType.longType()); + fieldName = IDLMethodParser.generateFieldName(classDeclaration, typeStr, true); + String newBody = IDLMethodParser.CALLBACK_PARAM_TEMPLATE + .replace(IDLMethodParser.TEMPLATE_TEMP_FIELD, fieldName) + .replace(IDLMethodParser.TEMPLATE_TAG_TYPE, typeStr) + .replace(IDLMethodParser.TEMPLATE_TAG_PARAM, paramName); + + createFieldObjectCode += newBody; + } + caller.addArgument(fieldName); } + createFieldObjectCode = "{\n" + createFieldObjectCode + "}"; + BlockStmt blockStmt = StaticJavaParser.parseBlock(createFieldObjectCode); + + if(internalMethod.getType().isVoidType()) { + blockStmt.addStatement(caller); + } + else { + ReturnStmt returnStmt = new ReturnStmt(); + returnStmt.setExpression(caller); + blockStmt.addStatement(returnStmt); + } + String internName = internalMethod.getNameAsString(); + internalMethod.setName("internal_" + internName); + internalMethod.setBody(blockStmt); + classDeclaration.addMember(internalMethod); + + Pair methodDeclarationPair = new Pair<>(internalMethod, methodDeclaration); + + Pair> methodPair = new Pair<>(method, methodDeclarationPair); + methods.add(methodPair); } + return methods; } } \ No newline at end of file diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java index 92b83b6b..49dfed34 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java @@ -96,7 +96,7 @@ public static MethodDeclaration setupConstructor(IDLConstructor idlConstructor, Type type = StaticJavaParser.parseType(classDeclaration.getNameAsString()); boolean isStatic = true; - MethodDeclaration nativeMethod = IDLMethodParser.generateNativeMethod(false, "create", parameters, type, isStatic); + MethodDeclaration nativeMethod = IDLMethodParser.generateNativeMethod("create", parameters, type, isStatic); if(!JParserHelper.containsMethod(classDeclaration, nativeMethod)) { //Add native method if it does not exist diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java index ed0c976a..4209202e 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java @@ -40,7 +40,7 @@ else if(size == 0) { if(deleteMethod != null) { NodeList parameters = deleteMethod.getParameters(); Type type = deleteMethod.getType(); - MethodDeclaration nativeMethod = IDLMethodParser.generateNativeMethod(false, DELETE_NATIVE, parameters, type, false); + MethodDeclaration nativeMethod = IDLMethodParser.generateNativeMethod(DELETE_NATIVE, parameters, type, false); if(!JParserHelper.containsMethod(classOrInterfaceDeclaration, nativeMethod)) { classOrInterfaceDeclaration.getMembers().add(nativeMethod); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java index 6e7bb29c..d735293b 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java @@ -12,6 +12,7 @@ import com.github.javaparser.ast.stmt.BlockStmt; import com.github.javaparser.ast.stmt.ReturnStmt; import com.github.javaparser.ast.type.Type; +import com.github.javaparser.utils.Pair; import com.github.xpenatan.jparser.core.JParser; import com.github.xpenatan.jparser.core.JParserHelper; import com.github.xpenatan.jparser.core.codeparser.CodeParserItem; @@ -128,7 +129,7 @@ public static void setDefaultReturnValues(JParser jParser, CompilationUnit unit, BlockStmt blockStmt = idlMethodDeclaration.getBody().get(); ReturnStmt returnStmt = new ReturnStmt(); if(returnType.isPrimitiveType()) { - if(JParserHelper.isLong(returnType) || JParserHelper.isInt(returnType) || JParserHelper.isFloat(returnType) || JParserHelper.isDouble(returnType)) { + if(JParserHelper.isLong(returnType) || JParserHelper.isInt(returnType) || JParserHelper.isFloat(returnType) || JParserHelper.isDouble(returnType) || JParserHelper.isShort(returnType)) { NameExpr returnNameExpr = new NameExpr(); returnNameExpr.setName("0"); returnStmt.setExpression(returnNameExpr); @@ -164,7 +165,7 @@ public void onIDLAttributeGenerated(JParser jParser, IDLAttribute idlAttribute, public void onIDLEnumMethodGenerated(JParser jParser, IDLEnum idlEnum, ClassOrInterfaceDeclaration classDeclaration, String enumStr, FieldDeclaration fieldDeclaration, MethodDeclaration nativeMethodDeclaration) { } - public void onIDLCallbackGenerated(JParser jParser, IDLClass idlClass, ClassOrInterfaceDeclaration classDeclaration) { + public void onIDLCallbackGenerated(JParser jParser, IDLClass idlClass, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration callbackDeclaration, ArrayList>> methods) { } public String getIDLMethodName(String name) { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java index 220f5f8b..838afe77 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java @@ -47,6 +47,10 @@ public class IDLMethodParser { " return [TYPE]_TEMP_GEN_[NUM];\n" + "}"; + static final String CALLBACK_PARAM_TEMPLATE = + "if([TYPE]_TEMP_GEN_[NUM] == null) [TYPE]_TEMP_GEN_[NUM] = new [TYPE]((byte)1, (char)1);\n" + + "[TYPE]_TEMP_GEN_[NUM].setCPointer([PARAM]);\n"; + static final String GET_TEMP_OBJECT_TEMPLATE = "{\n" + " [METHOD];\n" + @@ -64,25 +68,34 @@ public class IDLMethodParser { static final String TEMPLATE_TAG_METHOD = "[METHOD]"; + static final String TEMPLATE_TAG_PARAM = "[PARAM]"; + static final String TEMPLATE_TAG_TYPE = "[TYPE]"; static final String TEMPLATE_TAG_NUM = "[NUM]"; public static void generateMethod(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classOrInterfaceDeclaration, IDLClass idlClass, IDLMethod idlMethod) { + MethodDeclaration methodDeclaration = generateAndAddMethodOnly(idlParser, jParser, unit, classOrInterfaceDeclaration, idlMethod); + if(methodDeclaration != null && idlParser.generateClass) { + setupMethod(idlParser, jParser, idlMethod, classOrInterfaceDeclaration, methodDeclaration); + } + } + + public static MethodDeclaration generateAndAddMethodOnly(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classDeclaration, IDLMethod idlMethod) { if(idlMethod.skip) { - return; + return null; } String methodName = idlMethod.name; Type returnType = null; - MethodDeclaration containsMethod = containsMethod(idlParser, classOrInterfaceDeclaration, idlMethod); + MethodDeclaration containsMethod = containsMethod(idlParser, classDeclaration, idlMethod); if(containsMethod != null) { if(canGenerateMethod(containsMethod)) { returnType = containsMethod.getType(); } else { - return; + return null; } } @@ -91,11 +104,11 @@ public static void generateMethod(IDLDefaultCodeParser idlParser, JParser jParse String updatedMethodName = idlParser.getIDLMethodName(fixedMethodName); ArrayList parameters = idlMethod.parameters; - MethodDeclaration methodDeclaration = classOrInterfaceDeclaration.addMethod(updatedMethodName, Modifier.Keyword.PUBLIC); + MethodDeclaration methodDeclaration = classDeclaration.addMethod(updatedMethodName, Modifier.Keyword.PUBLIC); methodDeclaration.setStatic(idlMethod.isStaticMethod); for(int i = 0; i < parameters.size(); i++) { IDLParameter idlParameter = parameters.get(i); - String paramType = idlParameter.type; + String paramType = idlParameter.getType(); String paramName = idlParameter.name; paramType = IDLHelper.convertEnumToInt(idlParser.idlReader, paramType); Parameter parameter = methodDeclaration.addAndGetParameter(paramType, paramName); @@ -104,15 +117,12 @@ public static void generateMethod(IDLDefaultCodeParser idlParser, JParser jParse } if(returnType == null) { - String returnTypeStr = IDLHelper.convertEnumToInt(idlParser.idlReader, idlMethod.returnType); + String returnTypeStr = IDLHelper.convertEnumToInt(idlParser.idlReader, idlMethod.getReturnType()); returnType = StaticJavaParser.parseType(returnTypeStr); } methodDeclaration.setType(returnType); IDLDefaultCodeParser.setDefaultReturnValues(jParser, unit, returnType, methodDeclaration); - - if(idlParser.generateClass) { - setupMethod(idlParser, jParser, idlMethod, classOrInterfaceDeclaration, methodDeclaration); - } + return methodDeclaration; } public static boolean canGenerateMethod(MethodDeclaration containsMethod) { @@ -160,7 +170,7 @@ private static void setupMethod(IDLDefaultCodeParser idlParser, JParser jParser, public static MethodDeclaration prepareNativeMethod(boolean isStatic, boolean isReturnValue, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, String methodName, String operator, ArrayList idlParameters) { NodeList methodParameters = methodDeclaration.getParameters(); Type methodReturnType = methodDeclaration.getType(); - MethodDeclaration nativeMethodDeclaration = generateNativeMethod(isReturnValue, methodName, methodParameters, methodReturnType, methodDeclaration.isStatic()); + MethodDeclaration nativeMethodDeclaration = generateNativeMethod(methodName, methodParameters, methodReturnType, methodDeclaration.isStatic()); if(!JParserHelper.containsMethod(classDeclaration, nativeMethodDeclaration)) { //Add native method if it does not exist classDeclaration.getMembers().add(nativeMethodDeclaration); @@ -283,7 +293,7 @@ private static BlockStmt generateTempObjects(boolean isReturnValue, ClassOrInter return body; } - private static String generateFieldName(ClassOrInterfaceDeclaration classDeclaration, String fieldType, boolean isStatic) { + public static String generateFieldName(ClassOrInterfaceDeclaration classDeclaration, String fieldType, boolean isStatic) { // Will return a temp object. // Java variable will be created by checking its class, name and number. // if the temp object already exist it will increment variable number and create it. @@ -336,7 +346,7 @@ private static String getFieldName(String type, int number, boolean isStatic) { } } - public static MethodDeclaration generateNativeMethod(boolean isReturnValue, String methodName, NodeList methodParameters, Type methodReturnType, boolean isStatic) { + public static MethodDeclaration generateNativeMethod(String methodName, NodeList methodParameters, Type methodReturnType, boolean isStatic) { boolean isClassOrInterfaceType = methodReturnType.isClassOrInterfaceType(); // Clone some generated idl method settings diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index bf413995..4fd2a304 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -778,7 +778,7 @@ else if(expression.isLambdaExpr()) { resolvedType = expression.calculateResolvedType(); } catch(Throwable t) { - t.printStackTrace(); +// t.printStackTrace(); continue; } String type = null; From a3598fd15020572fe8931a5765afd2e8c88a249f Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 29 Aug 2024 22:38:56 -0300 Subject: [PATCH 105/186] fix parsing long long --- .../xpenatan/jparser/example/app/TestLib.java | 16 +++++++++++++++ .../lib/lib-build/src/main/cpp/TestLib.idl | 2 ++ .../src/main/cpp/source/TestLib/src/TestLib.h | 5 +++++ .../xpenatan/jparser/idl/IDLMethod.java | 20 ++++++++++++++----- .../xpenatan/jparser/idl/IDLParameter.java | 15 +++++++++++--- .../jparser/idl/parser/IDLMethodParser.java | 8 +++++++- 6 files changed, 57 insertions(+), 9 deletions(-) diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java index 352dd02f..6037fb75 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java @@ -245,6 +245,22 @@ private static boolean testMethodClass() { } test.dispose(); } + { + TestMethodClass test = new TestMethodClass(); + try { + long longLongValue01 = 4; + test.setMethod08(longLongValue01); + long retLongLongValue01 = test.getLongLongValue01(); + if(!(longLongValue01 == retLongLongValue01)) { + throw new RuntimeException("longLongValue01 == retLongLongValue01"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } return true; } diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index 190a69fd..26ca7d69 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -93,6 +93,7 @@ interface TestMethodClass { void setMethod05([Const] DOMString strValue01); void setMethod06([Const] TestObjectClass pointerObject01, TestObjectClass pointerObject02, [Const, Ref] TestObjectClass refObject01, [Ref] TestObjectClass refObject02); void setMethod07(TestObjectClass pointerObjectArray); + void setMethod08(long long longLongValue01); long getIntValue01(); long getIntValue02(); @@ -106,6 +107,7 @@ interface TestMethodClass { [Const, Ref] TestObjectClass getRefObject01(); [Ref] TestObjectClass getRefObject02(); [Value] TestObjectClass getValueObject(); + long long getLongLongValue01(); }; [NoDelete] diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h index 89964d17..fc0f6428 100644 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h @@ -124,6 +124,7 @@ class TestMethodClass { float floatValue01; float floatValue02; bool boolValue01; + long long longLongValue01; string strValue01; const TestObjectClass* pointerObject01; TestObjectClass* pointerObject02; @@ -181,6 +182,9 @@ class TestMethodClass { obj2->intValue01 = 40; obj2->floatValue01 = 30.8; }; + void setMethod08(long long longLongValue01) { + this->longLongValue01 = longLongValue01; + }; int getIntValue01() { return intValue01; }; int getIntValue02() { return intValue02; }; @@ -194,6 +198,7 @@ class TestMethodClass { const TestObjectClass& getRefObject01() { return refObject01; }; TestObjectClass& getRefObject02() { return refObject02; }; TestObjectClass getValueObject() { return refObject02; }; + long long getLongLongValue01() { return longLongValue01; }; }; class TestStaticMethodClass { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java index ebd6d874..7a43945c 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java @@ -63,12 +63,22 @@ public void initMethod(String line) { isStaticMethod = true; } - String[] s = leftSide.split(" "); - name = s[s.length-1]; - leftSide = leftSide.replace(name, "").trim(); - returnType = leftSide; + String[] s1 = leftSide.split(" "); + name = s1[s1.length-1]; + + returnType = ""; + int sss = s1.length - 1; + for(int i = 0; i < sss; i++) { + returnType += s1[i]; + if(i < sss-1) { + returnType += " "; + } + } - if(returnType.contains("long")) { + if(returnType.contains("long long")) { + returnType = returnType.replace("long long", "long"); + } + else if(returnType.contains("long")) { returnType = returnType.replace("long", "int"); } if(returnType.equals("DOMString")) { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java index 2e7871b1..b6ad5836 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java @@ -56,15 +56,24 @@ public void initParameter(String line) { String[] s1 = tmpLine.split(" "); name = s1[s1.length - 1]; - tmpLine = tmpLine.replace(name, "").trim(); - type = tmpLine; + type = ""; + int sss = s1.length - 1; + for(int i = 0; i < sss; i++) { + type += s1[i]; + if(i < sss-1) { + type += " "; + } + } if(isArray) { type = type + "[]"; } - if(type.contains("long")) { + if(type.contains("long long")) { + type = type.replace("long long", "long"); + } + else if(type.contains("long")) { // long in webidl means int type = type.replace("long", "int"); } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java index 838afe77..1fe6da7b 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java @@ -111,7 +111,13 @@ public static MethodDeclaration generateAndAddMethodOnly(IDLDefaultCodeParser id String paramType = idlParameter.getType(); String paramName = idlParameter.name; paramType = IDLHelper.convertEnumToInt(idlParser.idlReader, paramType); - Parameter parameter = methodDeclaration.addAndGetParameter(paramType, paramName); + Parameter parameter = null; + try { + parameter = methodDeclaration.addAndGetParameter(paramType, paramName); + } + catch(Throwable t) { + t.printStackTrace(); + } Type type = parameter.getType(); JParserHelper.addMissingImportType(jParser, unit, type); } From 3b963a322568c815c11935df1afb0bfbad3fe879 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 29 Aug 2024 23:01:10 -0300 Subject: [PATCH 106/186] Revert code --- .../xpenatan/jparser/idl/parser/IDLMethodParser.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java index 1fe6da7b..838afe77 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java @@ -111,13 +111,7 @@ public static MethodDeclaration generateAndAddMethodOnly(IDLDefaultCodeParser id String paramType = idlParameter.getType(); String paramName = idlParameter.name; paramType = IDLHelper.convertEnumToInt(idlParser.idlReader, paramType); - Parameter parameter = null; - try { - parameter = methodDeclaration.addAndGetParameter(paramType, paramName); - } - catch(Throwable t) { - t.printStackTrace(); - } + Parameter parameter = methodDeclaration.addAndGetParameter(paramType, paramName); Type type = parameter.getType(); JParserHelper.addMissingImportType(jParser, unit, type); } From 53a886955d317d587816d2069d55f02e600f7848 Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 31 Aug 2024 08:49:15 -0300 Subject: [PATCH 107/186] add namespace test --- .../xpenatan/jparser/example/app/TestLib.java | 40 ++++++++++++++++++- .../lib/lib-build/src/main/cpp/TestLib.idl | 8 ++++ .../src/main/cpp/source/TestLib/src/TestLib.h | 16 ++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java index 6037fb75..789b10ba 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java @@ -5,6 +5,7 @@ import com.github.xpenatan.jparser.example.testlib.TestCallbackClass; import com.github.xpenatan.jparser.example.testlib.TestConstructorClass; import com.github.xpenatan.jparser.example.testlib.TestMethodClass; +import com.github.xpenatan.jparser.example.testlib.TestNamespaceClass; import com.github.xpenatan.jparser.example.testlib.TestObjectClass; import com.github.xpenatan.jparser.example.testlib.TestObjectClassArray; import com.github.xpenatan.jparser.example.testlib.idl.helper.IDLString; @@ -21,6 +22,7 @@ public static boolean test() { boolean staticMethodTest = testStaticMethodClass(); boolean callbackTest = testCallbackClass(); boolean callbackTestManual = testCallbackClassManual(); + boolean namespaceTest = testNamespaceClass(); System.out.println("constructorTest: " + constructorTest); System.out.println("stringConstructorTest: " + stringConstructorTest); @@ -30,8 +32,9 @@ public static boolean test() { System.out.println("methodTest: " + methodTest); System.out.println("staticMethodTest: " + staticMethodTest); System.out.println("callbackTest: " + callbackTest); + System.out.println("namespaceTest: " + namespaceTest); return constructorTest && stringConstructorTest && attributeTest && staticAttributeTest - && attributeArrayTest && methodTest && staticMethodTest && callbackTest && callbackTestManual; + && attributeArrayTest && methodTest && staticMethodTest && callbackTest && callbackTestManual && namespaceTest; } private static boolean testConstructorClass() { @@ -429,7 +432,6 @@ public short onUnsignedShortCallback(short unsignedShort) { } private static boolean testCallbackClassManual() { - { TestCallbackClass test = new TestCallbackClass(); try { @@ -542,4 +544,38 @@ public void internal_onStringCallback(String strValue01) { } return true; } + + private static boolean testNamespaceClass() { + { + TestNamespaceClass test = new TestNamespaceClass(); + try { + int value = 20; + test.setMethod01Value(value); + if(!(value == test.getMethod01Value())) { + throw new RuntimeException("value == test.getMethod01Value()"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } + { + TestNamespaceClass test = new TestNamespaceClass(); + try { + int value = 40; + test.set_intValue01(value); + if(!(value == test.get_intValue01())) { + throw new RuntimeException("value == test.get_intValue01()"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } + return true; + } } \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index 26ca7d69..7551406b 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -206,6 +206,14 @@ interface TestCallbackClass { void callManualStringCallback(CallbackClassManual callback); }; +[Prefix="TestNamespace::"] +interface TestNamespaceClass { + attribute long intValue01; + void TestNamespaceClass(); + void setMethod01Value(long intValue01); + long getMethod01Value(); +}; + enum TestEnumWithinClass { "TestEnumClass::e_val" }; diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h index fc0f6428..8cd247ea 100644 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h @@ -380,6 +380,22 @@ class TestCallbackClass { }; }; + +namespace TestNamespace { + class TestNamespaceClass { + private: + public: + int intValue01; + + void setMethod01Value(int intValue01) { + this->intValue01 = intValue01; + } + int getMethod01Value() { + return intValue01; + } + }; +}; + class TestEnumClass { private: From a69d5ded23580b865ba755136f50b87d08f624c3 Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 31 Aug 2024 09:02:06 -0300 Subject: [PATCH 108/186] Fix, Don't add prefix to teavm class name --- .../java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index 4fd2a304..15948737 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -259,7 +259,7 @@ public void onIDLConstructorGenerated(JParser jParser, IDLConstructor idlConstru IDLClass idlClass = idlConstructor.idlClass; - String className = idlClass.getName(); + String className = idlClass.name; // teavm class cannot have prefix. MethodCallExpr caller = new MethodCallExpr(); caller.setName(className); From b047731884fd64df98ca3a1183180fedab0c8bb8 Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 31 Aug 2024 22:45:12 -0300 Subject: [PATCH 109/186] Fix generating constructor --- .../src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java | 2 +- .../xpenatan/jparser/idl/parser/IDLConstructorParser.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java index 443f48a8..5f93ff86 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java @@ -41,7 +41,7 @@ private void setAttributesAndMethods() { attributes.add(attribute); } else { - if(line.startsWith("void " + name)) { + if(line.contains("void " + name)) { IDLConstructor constructor = new IDLConstructor(idlFile, this); constructor.initConstructor(line); constructors.add(constructor); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java index 49dfed34..91bfe5b6 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java @@ -82,7 +82,7 @@ public static ConstructorDeclaration getOrCreateConstructorDeclaration(IDLDefaul ArrayList parameters = idlConstructor.parameters; for(int i = 0; i < parameters.size(); i++) { IDLParameter parameter = parameters.get(i); - String paramType = parameter.type; + String paramType = parameter.getType(); paramType = IDLHelper.convertEnumToInt(idlParser.idlReader, paramType); JParserHelper.addMissingImportType(jParser, unit, paramType); constructorDeclaration.addAndGetParameter(paramType, parameter.name); From 4e4ffabfe50adbfb6712f2675626c4332e6c3986 Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 31 Aug 2024 22:56:53 -0300 Subject: [PATCH 110/186] fix callback passing any --- example/lib/lib-build/src/main/cpp/TestLib.idl | 1 + .../lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h | 1 + .../java/com/github/xpenatan/jparser/idl/IDLParameter.java | 5 ++++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index 7551406b..903ac0a7 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -151,6 +151,7 @@ interface CallbackClassImpl { [Const] void onStringCallback([Const] DOMString strValue01); unsigned long onUnsignedIntCallback(unsigned long unsignedInt); [Const] unsigned short onUnsignedShortCallback(unsigned short unsignedShort); + [Const] void onAnyCallback(any anyPtr); }; CallbackClassImpl implements CallbackClass; diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h index 8cd247ea..377e0816 100644 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h @@ -270,6 +270,7 @@ class CallbackClass virtual void onStringCallback(const char* strValue01) const = 0; virtual unsigned int onUnsignedIntCallback(unsigned int unsignedInt) = 0; virtual unsigned short onUnsignedShortCallback(unsigned short unsignedShort) const = 0; + virtual void onAnyCallback(void * anyPtr) const = 0; int addInt(int a, int b) { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java index b6ad5836..d65cf8a3 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java @@ -79,7 +79,7 @@ else if(type.contains("long")) { } if(type.equals("any") || type.equals("VoidPtr")) { - type = "long"; + type = "void*"; isAny = true; } @@ -109,6 +109,9 @@ else if(type.equals("double[]")) { } public String getType() { + if(isAny) { + return "long"; + } return type.replace("unsigned", "").trim(); } From e1c344293b78dd6313699f1cf3b479e11ca2860f Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 1 Sep 2024 09:41:44 -0300 Subject: [PATCH 111/186] Add default callback test --- .../xpenatan/jparser/example/app/TestLib.java | 18 ++++++++++ .../lib/lib-build/src/main/cpp/TestLib.idl | 8 ++--- .../src/main/cpp/source/TestLib/src/TestLib.h | 36 ++++++++++--------- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java index 789b10ba..99a9b304 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java @@ -2,6 +2,7 @@ import com.github.xpenatan.jparser.example.testlib.CallbackClass; import com.github.xpenatan.jparser.example.testlib.CallbackClassManual; +import com.github.xpenatan.jparser.example.testlib.DefaultCallbackClass; import com.github.xpenatan.jparser.example.testlib.TestCallbackClass; import com.github.xpenatan.jparser.example.testlib.TestConstructorClass; import com.github.xpenatan.jparser.example.testlib.TestMethodClass; @@ -317,6 +318,23 @@ public int onIntCallback(int intValue01, int intValue02) { } test.dispose(); } + { + TestCallbackClass test = new TestCallbackClass(); + try { + test.set_intValue01(10); + test.set_intValue02(3); + CallbackClass callback = new DefaultCallbackClass(); + int value = test.callIntCallback(callback); + if(!(value == 7)) { + throw new RuntimeException("value == 7"); + } + } catch(Throwable e) { + e.printStackTrace(); + test.dispose(); + return false; + } + test.dispose(); + } { TestCallbackClass test = new TestCallbackClass(); try { diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index 903ac0a7..10be8502 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -167,10 +167,10 @@ interface CallbackClassManualImpl { }; CallbackClassManualImpl implements CallbackClassManual; -//interface DefaultCallbackClass { -// void DefaultCallbackClass(); -//}; -//DefaultCallbackClass implements CallbackClass; +interface DefaultCallbackClass { + void DefaultCallbackClass(); +}; +DefaultCallbackClass implements CallbackClass; //[JSImplementation="DefaultCallbackClass"] //interface DefaultCallbackClassImpl { diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h index 377e0816..9bf6e9f9 100644 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h @@ -278,23 +278,6 @@ class CallbackClass } }; -class CallbackClassManual -{ -public: - virtual ~CallbackClassManual() {} - - virtual void onVoidCallback(TestObjectClass& refData, TestObjectClass* pointerData) const = 0; - virtual int onIntCallback(int intValue01, int intValue02) const = 0; - virtual float onFloatCallback(float floatValue01, float Value02) const = 0; - virtual bool onBoolCallback(bool boolValue01) const = 0; - virtual void onStringCallback(const char* strValue01) const = 0; - - int addInt(int a, int b) - { - return a + b; - } -}; - class DefaultCallbackClass : public CallbackClass { public: @@ -324,6 +307,25 @@ class DefaultCallbackClass : public CallbackClass virtual unsigned short onUnsignedShortCallback(unsigned short unsignedShort) const { return 20; } + virtual void onAnyCallback(void * anyPtr) const { + } +}; + +class CallbackClassManual +{ +public: + virtual ~CallbackClassManual() {} + + virtual void onVoidCallback(TestObjectClass& refData, TestObjectClass* pointerData) const = 0; + virtual int onIntCallback(int intValue01, int intValue02) const = 0; + virtual float onFloatCallback(float floatValue01, float Value02) const = 0; + virtual bool onBoolCallback(bool boolValue01) const = 0; + virtual void onStringCallback(const char* strValue01) const = 0; + + int addInt(int a, int b) + { + return a + b; + } }; class TestCallbackClass { From bbaaeb68d18dc4a36340a3a3509e69e4c519cf9c Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 1 Sep 2024 09:55:35 -0300 Subject: [PATCH 112/186] Add inherited interfaces support using colon --- example/lib/lib-build/src/main/cpp/TestLib.idl | 3 +-- .../github/xpenatan/jparser/idl/IDLClass.java | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index 10be8502..0792c008 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -167,10 +167,9 @@ interface CallbackClassManualImpl { }; CallbackClassManualImpl implements CallbackClassManual; -interface DefaultCallbackClass { +interface DefaultCallbackClass : CallbackClass { void DefaultCallbackClass(); }; -DefaultCallbackClass implements CallbackClass; //[JSImplementation="DefaultCallbackClass"] //interface DefaultCallbackClassImpl { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java index 5f93ff86..d3f52194 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java @@ -27,12 +27,12 @@ public IDLClass(IDLFile idlFile) { public void initClass(ArrayList lines) { classLines.addAll(lines); setupHeader(); - setInterfaceName(); + setupInterfaceName(); setupExtendClass(); - setAttributesAndMethods(); + setupAttributesAndMethods(); } - private void setAttributesAndMethods() { + private void setupAttributesAndMethods() { for(int i = 1; i < classLines.size(); i++) { String line = classLines.get(i); if(line.contains("attribute ")) { @@ -75,7 +75,7 @@ private void setAttributesAndMethods() { } } - private void setInterfaceName() { + private void setupInterfaceName() { String line = searchLine("interface ", true, false); if(line != null) { name = line.split(" ")[1]; @@ -99,6 +99,15 @@ private void setupExtendClass() { String[] split = line.split("implements"); extendClass = split[1].trim().replace(";", ""); } + if(extendClass.isEmpty()) { + // If implements is not found check for : + String interfaceLine = searchLine("interface ", true, false); + if(interfaceLine != null && interfaceLine.contains(":")) { + String[] colonSplit = interfaceLine.split(":"); + String[] spaceSplit = colonSplit[1].trim().split(" "); + extendClass = spaceSplit[0].trim(); + } + } } private String searchLine(String text, boolean startsWith, boolean endsWith) { From d21854a3bdb9c634be6bed57249ccb96decd723c Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 1 Sep 2024 19:01:35 -0300 Subject: [PATCH 113/186] Don't generate constructor if it's a callback --- .../idl/parser/IDLConstructorParser.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java index 91bfe5b6..6253f122 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java @@ -26,13 +26,16 @@ public class IDLConstructorParser { public static void generateConstructor(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classOrInterfaceDeclaration, IDLClass idlClass) { ArrayList constructors = idlClass.constructors; - for(int i = 0; i < constructors.size(); i++) { - IDLConstructor idlConstructor = constructors.get(i); - ConstructorDeclaration constructorDeclaration = IDLConstructorParser.getOrCreateConstructorDeclaration(idlParser, jParser, unit, classOrInterfaceDeclaration, idlConstructor); - - if(constructorDeclaration.getBody().isEmpty()) { - MethodDeclaration nativeMethod = IDLConstructorParser.setupConstructor(idlConstructor, classOrInterfaceDeclaration, constructorDeclaration); - idlParser.onIDLConstructorGenerated(jParser, idlConstructor, classOrInterfaceDeclaration, constructorDeclaration, nativeMethod); + if(idlClass.callback == null) { + // Generate constructors only if it's not callback + for(int i = 0; i < constructors.size(); i++) { + IDLConstructor idlConstructor = constructors.get(i); + ConstructorDeclaration constructorDeclaration = IDLConstructorParser.getOrCreateConstructorDeclaration(idlParser, jParser, unit, classOrInterfaceDeclaration, idlConstructor); + + if(constructorDeclaration.getBody().isEmpty()) { + MethodDeclaration nativeMethod = IDLConstructorParser.setupConstructor(idlConstructor, classOrInterfaceDeclaration, constructorDeclaration); + idlParser.onIDLConstructorGenerated(jParser, idlConstructor, classOrInterfaceDeclaration, constructorDeclaration, nativeMethod); + } } } From 2cef09bd51984d35222727fdd13684fde5ba0b0f Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 1 Sep 2024 19:01:45 -0300 Subject: [PATCH 114/186] add long long param support --- example/lib/lib-build/src/main/cpp/TestLib.idl | 1 + .../lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h | 3 +++ .../java/com/github/xpenatan/jparser/idl/IDLParameter.java | 5 ++++- .../xpenatan/jparser/idl/parser/IDLCallbackParser.java | 2 -- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index 0792c008..328e9d26 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -152,6 +152,7 @@ interface CallbackClassImpl { unsigned long onUnsignedIntCallback(unsigned long unsignedInt); [Const] unsigned short onUnsignedShortCallback(unsigned short unsignedShort); [Const] void onAnyCallback(any anyPtr); + [Const] void onLongLongValue(unsigned long long longLongValue); }; CallbackClassImpl implements CallbackClass; diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h index 9bf6e9f9..c08af8bf 100644 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h @@ -271,6 +271,7 @@ class CallbackClass virtual unsigned int onUnsignedIntCallback(unsigned int unsignedInt) = 0; virtual unsigned short onUnsignedShortCallback(unsigned short unsignedShort) const = 0; virtual void onAnyCallback(void * anyPtr) const = 0; + virtual void onLongLongValue(unsigned long long longLongValue) const = 0; int addInt(int a, int b) { @@ -309,6 +310,8 @@ class DefaultCallbackClass : public CallbackClass } virtual void onAnyCallback(void * anyPtr) const { } + virtual void onLongLongValue(unsigned long long longLongValue) const { + } }; class CallbackClassManual diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java index d65cf8a3..36734a25 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java @@ -71,7 +71,7 @@ public void initParameter(String line) { } if(type.contains("long long")) { - type = type.replace("long long", "long"); + // Keep c++ long long } else if(type.contains("long")) { // long in webidl means int @@ -112,6 +112,9 @@ public String getType() { if(isAny) { return "long"; } + if(type.contains("long long")) { + return "long"; + } return type.replace("unsigned", "").trim(); } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java index 5f443048..77ae9e82 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java @@ -25,8 +25,6 @@ public class IDLCallbackParser { private final static String callbackMethodName = "setupCallback"; public static void generateCallback(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classDeclaration, IDLClass idlClass) { - - ArrayList constructors = idlClass.callback.constructors; if(constructors.size() == 1) { IDLConstructor idlConstructor = constructors.get(0); From 7dc4150cf7cd4fb0110b068cec5d5f874b1c2614 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 1 Sep 2024 20:46:27 -0300 Subject: [PATCH 115/186] Add cpp callback overload solution --- .../lib/lib-build/src/main/cpp/TestLib.idl | 1 + .../src/main/cpp/source/TestLib/src/TestLib.h | 3 ++ .../xpenatan/jparser/cpp/CppCodeParser.java | 43 +++++++++++++++---- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index 328e9d26..542be585 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -152,6 +152,7 @@ interface CallbackClassImpl { unsigned long onUnsignedIntCallback(unsigned long unsignedInt); [Const] unsigned short onUnsignedShortCallback(unsigned short unsignedShort); [Const] void onAnyCallback(any anyPtr); + [Const] void onAnyCallback(any anyPtr, long value); [Const] void onLongLongValue(unsigned long long longLongValue); }; CallbackClassImpl implements CallbackClass; diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h index c08af8bf..270d8067 100644 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h @@ -271,6 +271,7 @@ class CallbackClass virtual unsigned int onUnsignedIntCallback(unsigned int unsignedInt) = 0; virtual unsigned short onUnsignedShortCallback(unsigned short unsignedShort) const = 0; virtual void onAnyCallback(void * anyPtr) const = 0; + virtual void onAnyCallback(void * anyPtr, int value) const = 0; virtual void onLongLongValue(unsigned long long longLongValue) const = 0; int addInt(int a, int b) @@ -310,6 +311,8 @@ class DefaultCallbackClass : public CallbackClass } virtual void onAnyCallback(void * anyPtr) const { } + virtual void onAnyCallback(void * anyPtr, int value) const { + } virtual void onLongLongValue(unsigned long long longLongValue) const { } }; diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index 0bbf2f15..6fce04a0 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -465,7 +465,7 @@ private String generateSetupCallbackMethod(IDLClass idlClass, MethodDeclaration String staticVariables = ""; String methodIds = ""; - String methodName = callbackDeclaration.getNameAsString(); + String callbackMethodName = callbackDeclaration.getNameAsString(); for(int i = 0; i < methods.size(); i++) { Pair> pair = methods.get(i); @@ -494,11 +494,14 @@ else if(type.isClassOrInterfaceType()) { } } } + String methodCode = generateMethodID(internalMethod); paramCode = "(" + paramCode + ")" + JNITypeSignature.getJNIType(returnTypeStr); - String variable = variableTemplate.replace("[METHOD]", idlMethod.name); - String methodId = methodIdTemplate.replace("[METHOD]", idlMethod.name) + String methodName = idlMethod.name + methodCode; + + String variable = variableTemplate.replace("[METHOD]", methodName); + String methodId = methodIdTemplate.replace("[METHOD]", methodName) .replace("[CLASS_NAME]", className) .replace("[INTERNAL_METHOD]", internalMethodName) .replace("[PARAM_CODE]", paramCode); @@ -507,21 +510,42 @@ else if(type.isClassOrInterfaceType()) { } String content = contentTemplate.replace("[VARIABLES]", staticVariables) - .replace("[METHOD]", methodName) + .replace("[METHOD]", callbackMethodName) .replace("[CLASS_NAME]", className) .replace("[METHOD_IDS]", methodIds); return content; } + private String generateMethodID(MethodDeclaration internalMethod) { + // Method is used when there is multiple overloaded methods + String methodCode = ""; + NodeList parameters = internalMethod.getParameters(); + for(int i1 = 0; i1 < parameters.size(); i1++) { + Parameter parameter = parameters.get(i1); + Type type = parameter.getType(); + String typeStr = type.asString(); + if(type.isPrimitiveType()) { + String jniType = JNITypeSignature.getJNIType(typeStr); + methodCode += jniType; + } + else if(type.isClassOrInterfaceType()) { + if(typeStr.equals("String")) { + methodCode += "S"; + } + } + } + return methodCode; + } + private String generateMethodCallers(IDLClass idlClass, ArrayList>> methods) { IDLClass callback = idlClass.callback; String cppMethods = ""; String cppClassName = callback.name; String methodTemplate = "" + - "virtual [RETURN_TYPE] [METHOD]([PARAMS])[CONST] {\n" + - " [RETURN]env->[CALL_METHOD](obj, [CPP_CLASS]::[METHOD]_ID[CALL_PARAMS]);\n" + + "virtual [RETURN_TYPE] [METHOD_NAME]([PARAMS])[CONST] {\n" + + " [RETURN]env->[CALL_METHOD](obj, [CPP_CLASS]::[METHOD_ID]_ID[CALL_PARAMS]);\n" + "}\n"; for(int i = 0; i < methods.size(); i++) { @@ -535,6 +559,8 @@ private String generateMethodCallers(IDLClass idlClass, ArrayList Date: Sun, 1 Sep 2024 20:49:15 -0300 Subject: [PATCH 116/186] Create FUNDING.yml --- .github/FUNDING.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..ac7c0848 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,15 @@ +# These are supported funding model platforms + +github: [xpenatan] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry +polar: # Replace with a single Polar username +buy_me_a_coffee: # Replace with a single Buy Me a Coffee username +thanks_dev: # Replace with a single thanks.dev username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] From cf8d6d78ee9d8fc515b54f14ee63f3f22227f09e Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 2 Sep 2024 08:34:31 -0300 Subject: [PATCH 117/186] Update callback overloading solution --- example/lib/lib-build/src/main/cpp/TestLib.idl | 7 ++++--- .../lib-build/src/main/cpp/source/TestLib/src/TestLib.h | 8 ++++---- .../jparser/builder/targets/EmscriptenTarget.java | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index 542be585..6178e30a 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -10,7 +10,8 @@ // * Arrays parameters for example "void method(int[] array)" is converted to IDLIntArray class object behind the scene because interacting with array is better using native code. // For custom types is better to use typedef. See TestObjectClassArray in CustomCode.h // * Array get_ shape the same object for every index. Don't keep object reference. - +// * Emscripten WebIDL callbacks don't work with overloaded methods so its better to use _[N] at the end of the method +// * Emscripten class methods don't work with overloaded methods with different parameter order so its better to use _[N] at the end of the method interface TestObjectClass { void TestObjectClass(); @@ -151,8 +152,8 @@ interface CallbackClassImpl { [Const] void onStringCallback([Const] DOMString strValue01); unsigned long onUnsignedIntCallback(unsigned long unsignedInt); [Const] unsigned short onUnsignedShortCallback(unsigned short unsignedShort); - [Const] void onAnyCallback(any anyPtr); - [Const] void onAnyCallback(any anyPtr, long value); + [Const] void onAnyCallback_1(any anyPtr); + [Const] void onAnyCallback_2(any anyPtr, long value); [Const] void onLongLongValue(unsigned long long longLongValue); }; CallbackClassImpl implements CallbackClass; diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h index 270d8067..1dbc9706 100644 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h @@ -270,8 +270,8 @@ class CallbackClass virtual void onStringCallback(const char* strValue01) const = 0; virtual unsigned int onUnsignedIntCallback(unsigned int unsignedInt) = 0; virtual unsigned short onUnsignedShortCallback(unsigned short unsignedShort) const = 0; - virtual void onAnyCallback(void * anyPtr) const = 0; - virtual void onAnyCallback(void * anyPtr, int value) const = 0; + virtual void onAnyCallback_1(void * anyPtr) const = 0; + virtual void onAnyCallback_2(void * anyPtr, int value) const = 0; virtual void onLongLongValue(unsigned long long longLongValue) const = 0; int addInt(int a, int b) @@ -309,9 +309,9 @@ class DefaultCallbackClass : public CallbackClass virtual unsigned short onUnsignedShortCallback(unsigned short unsignedShort) const { return 20; } - virtual void onAnyCallback(void * anyPtr) const { + virtual void onAnyCallback_1(void * anyPtr) const { } - virtual void onAnyCallback(void * anyPtr, int value) const { + virtual void onAnyCallback_2(void * anyPtr, int value) const { } virtual void onLongLongValue(unsigned long long longLongValue) const { } diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java index 18bc03ad..f52ff3ad 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java @@ -9,8 +9,8 @@ public class EmscriptenTarget extends DefaultBuildTarget { - public static boolean SKIP_GLUE_CODE; - public final static String EMSCRIPTEN_ROOT = System.getenv("EMSDK") + "/upstream/emscripten/"; + public static boolean SKIP_GLUE_CODE = false; + public final static String EMSCRIPTEN_ROOT = (System.getenv("EMSDK") + "/upstream/emscripten/").replace("\\", "/").replace("//", "/"); public IDLReader idlReader; From fb30318185fb11c98832d58ab9e197a7ade9ae05 Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 2 Sep 2024 12:46:49 -0300 Subject: [PATCH 118/186] Fix comparing method --- .../com/github/xpenatan/jparser/cpp/CppCodeParser.java | 10 ++++------ .../com/github/xpenatan/jparser/idl/IDLMethod.java | 6 +++++- .../com/github/xpenatan/jparser/idl/IDLParameter.java | 6 +++++- .../jparser/idl/parser/IDLConstructorParser.java | 4 ++-- .../xpenatan/jparser/idl/parser/IDLMethodParser.java | 6 +++--- .../github/xpenatan/jparser/teavm/TeaVMCodeParser.java | 2 +- 6 files changed, 20 insertions(+), 14 deletions(-) diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index 6fce04a0..9c39dd82 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -9,10 +9,8 @@ import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.Parameter; -import com.github.javaparser.ast.comments.BlockComment; import com.github.javaparser.ast.expr.MethodCallExpr; import com.github.javaparser.ast.stmt.BlockStmt; -import com.github.javaparser.ast.type.PrimitiveType; import com.github.javaparser.ast.type.Type; import com.github.javaparser.utils.Pair; import com.github.xpenatan.jparser.core.JParser; @@ -557,7 +555,7 @@ private String generateMethodCallers(IDLClass idlClass, ArrayList parameters, ArrayList 0) { param += ", "; } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java index 7a43945c..77494912 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java @@ -91,7 +91,11 @@ else if(returnType.contains("long")) { } } - public String getReturnType() { + public String getCPPReturnType() { + return returnType; + } + + public String getJavaReturnType() { return returnType.replace("unsigned", "").trim(); } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java index 36734a25..f3712612 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java @@ -108,7 +108,11 @@ else if(type.equals("double[]")) { } } - public String getType() { + public String getCPPReturnType() { + return type; + } + + public String getJavaType() { if(isAny) { return "long"; } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java index 6253f122..73fd5978 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java @@ -85,7 +85,7 @@ public static ConstructorDeclaration getOrCreateConstructorDeclaration(IDLDefaul ArrayList parameters = idlConstructor.parameters; for(int i = 0; i < parameters.size(); i++) { IDLParameter parameter = parameters.get(i); - String paramType = parameter.getType(); + String paramType = parameter.getJavaType(); paramType = IDLHelper.convertEnumToInt(idlParser.idlReader, paramType); JParserHelper.addMissingImportType(jParser, unit, paramType); constructorDeclaration.addAndGetParameter(paramType, parameter.name); @@ -126,7 +126,7 @@ public static ConstructorDeclaration containsConstructor(ClassOrInterfaceDeclara String[] paramTypes = new String[parameters.size()]; for(int i = 0; i < parameters.size(); i++) { IDLParameter parameter = parameters.get(i); - String paramType = parameter.type; + String paramType = parameter.getJavaType(); paramTypes[i] = paramType; } Optional constructorDeclarationOptional = classOrInterfaceDeclaration.getConstructorByParameterTypes(paramTypes); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java index 838afe77..59388524 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java @@ -108,7 +108,7 @@ public static MethodDeclaration generateAndAddMethodOnly(IDLDefaultCodeParser id methodDeclaration.setStatic(idlMethod.isStaticMethod); for(int i = 0; i < parameters.size(); i++) { IDLParameter idlParameter = parameters.get(i); - String paramType = idlParameter.getType(); + String paramType = idlParameter.getJavaType(); String paramName = idlParameter.name; paramType = IDLHelper.convertEnumToInt(idlParser.idlReader, paramType); Parameter parameter = methodDeclaration.addAndGetParameter(paramType, paramName); @@ -117,7 +117,7 @@ public static MethodDeclaration generateAndAddMethodOnly(IDLDefaultCodeParser id } if(returnType == null) { - String returnTypeStr = IDLHelper.convertEnumToInt(idlParser.idlReader, idlMethod.getReturnType()); + String returnTypeStr = IDLHelper.convertEnumToInt(idlParser.idlReader, idlMethod.getJavaReturnType()); returnType = StaticJavaParser.parseType(returnTypeStr); } methodDeclaration.setType(returnType); @@ -403,7 +403,7 @@ private static MethodDeclaration containsMethod(IDLDefaultCodeParser idlParser, for(int i = 0; i < parameters.size(); i++) { IDLParameter parameter = parameters.get(i); - String paramType = parameter.type; + String paramType = parameter.getJavaType(); paramType = IDLHelper.convertEnumToInt(idlParser.idlReader, paramType); paramTypes[i] = paramType; } diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index 15948737..754bc345 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -409,7 +409,7 @@ private static String getParams(NodeList parameters, ArrayList 0) { param += ", "; } From 91208fe79cdfaafc1a3c6bc55585c9ca015464ae Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 2 Sep 2024 17:53:59 -0300 Subject: [PATCH 119/186] fix add super method in callback --- .../github/xpenatan/jparser/idl/parser/IDLCallbackParser.java | 3 +++ .../xpenatan/jparser/idl/parser/IDLConstructorParser.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java index 77ae9e82..e0ab3355 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java @@ -38,6 +38,9 @@ public static void generateCallback(IDLDefaultCodeParser idlParser, JParser jPar MethodCallExpr caller = IDLMethodParser.createCaller(callbackSetupDeclaration); constructorDeclaration.getBody().addStatement(caller); idlParser.onIDLCallbackGenerated(jParser, idlClass, classDeclaration, callbackSetupDeclaration, methods); + + // Add super methods when its needed + IDLConstructorParser.addSuperTempConstructor(classDeclaration, constructorDeclaration); } } else { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java index 73fd5978..e010e931 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java @@ -56,7 +56,7 @@ public static void generateConstructor(IDLDefaultCodeParser idlParser, JParser j } } - private static void addSuperTempConstructor(ClassOrInterfaceDeclaration classDeclaration, ConstructorDeclaration constructorDeclaration) { + public static void addSuperTempConstructor(ClassOrInterfaceDeclaration classDeclaration, ConstructorDeclaration constructorDeclaration) { Optional parent = classDeclaration.getExtendedTypes().getFirst(); String parentName = ""; if(parent.isPresent()) { From f3fa09a931d28cd0a0ecd9b8956853c64f71abd5 Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 2 Sep 2024 20:52:57 -0300 Subject: [PATCH 120/186] remove print --- .../main/java/com/github/xpenatan/jparser/builder/JProcess.java | 1 - .../java/com/github/xpenatan/jparser/cpp/CppCodeParser.java | 2 -- 2 files changed, 3 deletions(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/JProcess.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/JProcess.java index e77b970a..3afb54cc 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/JProcess.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/JProcess.java @@ -37,7 +37,6 @@ public static boolean startProcess (File directory, String[] commands) { String command = commands[i]; System.out.println("Param: " + command); } - System.out.println(); final Process process = new ProcessBuilder(commands) .redirectErrorStream(true) diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index 9c39dd82..38aface5 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -439,8 +439,6 @@ private void generateCPPClass(IDLClass idlClass, ClassOrInterfaceDeclaration cla String code = header + cppClass; classDeclaration.getConstructors().get(0).setBlockComment(code); - - System.out.println(); } private String generateSetupCallbackMethod(IDLClass idlClass, MethodDeclaration callbackDeclaration, ArrayList>> methods) { From 6fba6ea4faa6bd448591aced08d670131c6e2e9a Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 3 Sep 2024 22:39:52 -0300 Subject: [PATCH 121/186] Fix/Improve converting idl type to java or cpp --- .../xpenatan/jparser/cpp/CppCodeParser.java | 15 ++- .../xpenatan/jparser/idl/IDLAttribute.java | 33 +++-- .../xpenatan/jparser/idl/IDLHelper.java | 115 +++++++++++++++++- .../xpenatan/jparser/idl/IDLMethod.java | 15 +-- .../xpenatan/jparser/idl/IDLParameter.java | 60 ++------- .../jparser/idl/IDLTypeConverterListener.java | 5 + .../idl/parser/IDLAttributeParser.java | 4 +- .../xpenatan/jparser/idl/IDLReaderTest.java | 28 ++--- .../jparser/teavm/TeaVMCodeParser.java | 1 - 9 files changed, 174 insertions(+), 102 deletions(-) create mode 100644 jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLTypeConverterListener.java diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index 38aface5..f471f3c1 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -251,7 +251,7 @@ public void onIDLAttributeGenerated(JParser jParser, IDLAttribute idlAttribute, } String getPrimitiveCast = ""; - String attributeType = idlAttribute.type; + String attributeType = idlAttribute.getCPPType(); String constTag = ""; if(idlAttribute.isConst) { constTag = "const "; @@ -569,8 +569,8 @@ private String generateMethodCallers(IDLClass idlClass, ArrayList parameters, ArrayList 0) { param += ", "; } @@ -771,7 +771,12 @@ private static String getParams(NodeList parameters, ArrayList methods = classOrInterfaceDeclaration.getMethodsBySignature(methodName, paramTypes); diff --git a/jParser/idl/src/test/java/com/github/xpenatan/jparser/idl/IDLReaderTest.java b/jParser/idl/src/test/java/com/github/xpenatan/jparser/idl/IDLReaderTest.java index 36318e4b..17be7d6d 100644 --- a/jParser/idl/src/test/java/com/github/xpenatan/jparser/idl/IDLReaderTest.java +++ b/jParser/idl/src/test/java/com/github/xpenatan/jparser/idl/IDLReaderTest.java @@ -49,24 +49,24 @@ public void test_NoDeleteClassTest_attributes() { Assert.assertEquals("ReadOnlyInt", idlAttribute.name); Assert.assertTrue(idlClass.attributes.get(0).isStatic); Assert.assertTrue(idlClass.attributes.get(0).isReadOnly); - Assert.assertEquals("int", idlClass.attributes.get(0).type); + Assert.assertEquals("unsigned long", idlClass.attributes.get(0).idlType); Assert.assertTrue(idlClass.attributes.get(1).isConst); Assert.assertEquals("constNormalClass", idlClass.attributes.get(1).name); - Assert.assertEquals("NormalClassTest", idlClass.attributes.get(1).type); + Assert.assertEquals("NormalClassTest", idlClass.attributes.get(1).idlType); Assert.assertEquals("valueNormalClass", idlClass.attributes.get(2).name); Assert.assertTrue(idlClass.attributes.get(2).isValue); - Assert.assertEquals("NormalClassTest", idlClass.attributes.get(2).type); + Assert.assertEquals("NormalClassTest", idlClass.attributes.get(2).idlType); Assert.assertEquals("floatAttribute", idlClass.attributes.get(3).name); - Assert.assertEquals("float", idlClass.attributes.get(3).type); - Assert.assertEquals("NormalClassTest", idlClass.attributes.get(2).type); + Assert.assertEquals("float", idlClass.attributes.get(3).idlType); + Assert.assertEquals("NormalClassTest", idlClass.attributes.get(2).idlType); Assert.assertEquals("boolAttribute", idlClass.attributes.get(4).name); - Assert.assertEquals("boolean", idlClass.attributes.get(4).type); + Assert.assertEquals("boolean", idlClass.attributes.get(4).idlType); Assert.assertEquals("arrayBoolean", idlClass.attributes.get(6).name); - Assert.assertEquals("boolean[]", idlClass.attributes.get(6).type); + Assert.assertEquals("boolean[]", idlClass.attributes.get(6).idlType); Assert.assertEquals("arrayInt", idlClass.attributes.get(7).name); - Assert.assertEquals("int[]", idlClass.attributes.get(7).type); + Assert.assertEquals("unsigned long[]", idlClass.attributes.get(7).idlType); Assert.assertEquals("anyObject", idlClass.attributes.get(8).name); - Assert.assertEquals("any", idlClass.attributes.get(8).type); + Assert.assertEquals("any", idlClass.attributes.get(8).idlType); Assert.assertTrue(idlClass.attributes.get(8).isAny); } @@ -77,17 +77,17 @@ public void test_NoDeleteClassTest_methods() { IDLMethod idlMethod = idlClass.methods.get(1); Assert.assertEquals("getExtendClass", idlMethod.name); Assert.assertEquals("ExtendClassTest", idlMethod.returnType); - Assert.assertEquals("float", idlMethod.parameters.get(0).type); - Assert.assertEquals("int", idlMethod.parameters.get(1).type); - Assert.assertEquals("NormalClassTest", idlMethod.parameters.get(2).type); + Assert.assertEquals("float", idlMethod.parameters.get(0).idlType); + Assert.assertEquals("long", idlMethod.parameters.get(1).idlType); + Assert.assertEquals("NormalClassTest", idlMethod.parameters.get(2).idlType); Assert.assertEquals("normalClass", idlMethod.parameters.get(2).name); - Assert.assertEquals("IDLFloatArray", idlMethod.parameters.get(3).type); + Assert.assertEquals("float[]", idlMethod.parameters.get(3).idlType); Assert.assertTrue(idlMethod.parameters.get(3).isArray); Assert.assertEquals("vertices", idlMethod.parameters.get(3).name); Assert.assertTrue(idlMethod.parameters.get(2).isRef); Assert.assertTrue(idlMethod.parameters.get(2).isConst); IDLMethod flagsMethod = idlClass.getMethod("GetFlags"); - Assert.assertEquals("int", flagsMethod.returnType); + Assert.assertEquals("unsigned long", flagsMethod.returnType); IDLMethod copyNormalClassMethod = idlClass.getMethod("copyNormalClass"); Assert.assertTrue(copyNormalClassMethod.isReturnRef); Assert.assertEquals("=", copyNormalClassMethod.operator); diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index 754bc345..94b62db0 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -431,7 +431,6 @@ public void onIDLAttributeGenerated(JParser jParser, IDLAttribute idlAttribute, String returnTypeName = classDeclaration.getNameAsString(); String attributeName = idlAttribute.name; - String returnType = idlAttribute.type; String param = ""; NodeList parameters = nativeMethod.getParameters(); From 06efacde7eb0ccac7b543c888fb4dd44021e0c45 Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 14 Sep 2024 17:25:51 -0300 Subject: [PATCH 122/186] print pointer --- jParser/base/src/main/java/idl/IDLBase.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/jParser/base/src/main/java/idl/IDLBase.java b/jParser/base/src/main/java/idl/IDLBase.java index 10ebf97a..c15809b5 100644 --- a/jParser/base/src/main/java/idl/IDLBase.java +++ b/jParser/base/src/main/java/idl/IDLBase.java @@ -36,6 +36,11 @@ public void dispose() { nativeData.dispose(); } + @Override + public String toString() { + return getClass().getSimpleName() + " " + nativeData; + } + /** * Deletes the IDL object this class encapsulates. Do not call directly, instead use the {@link #dispose()} method. */ From 2f3a003775f486d38dff56f30ae0a2c5a54ba775 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 14 Nov 2024 14:25:28 -0300 Subject: [PATCH 123/186] Update loader code --- .../xpenatan/jparser/loader/JParserLibraryLoader.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java b/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java index ca566f78..62e972f6 100644 --- a/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java +++ b/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java @@ -1,5 +1,6 @@ package emu.com.github.xpenatan.jparser.loader; +import com.github.xpenatan.gdx.backends.teavm.assetloader.AssetInstance; import com.github.xpenatan.gdx.backends.teavm.assetloader.AssetLoader; import com.github.xpenatan.gdx.backends.teavm.assetloader.AssetLoaderListener; import com.github.xpenatan.jparser.loader.JParserLibraryLoaderListener; @@ -29,9 +30,9 @@ public void loadInternal(String libraryName, JParserLibraryLoaderListener listen return; } loadedLibraries.add(libraryName); - AssetLoader.AssetLoad instance = AssetLoader.getInstance(); + AssetLoader instance = AssetInstance.getLoaderInstance(); if(listener != null) { - instance.loadScript(true, libraryName, new AssetLoaderListener<>(){ + instance.loadScript(libraryName, new AssetLoaderListener<>(){ @Override public void onSuccess(String url, String result) { listener.onLoad(true); @@ -42,8 +43,5 @@ public void onFailure(String url) { } }); } - else { - instance.loadScript(false, libraryName, null); - } } } \ No newline at end of file From 8d7ca5174b835d09f4ecb22f7583bd1a8e171521 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 14 Nov 2024 14:26:32 -0300 Subject: [PATCH 124/186] Update loader code --- .../github/xpenatan/jparser/loader/JParserLibraryLoader.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java b/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java index 62e972f6..e672a512 100644 --- a/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java +++ b/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java @@ -43,5 +43,8 @@ public void onFailure(String url) { } }); } + else { + instance.loadScript(libraryName); + } } } \ No newline at end of file From 809d816bdebb877a6eaa1dff864c897c29f982c5 Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 9 Dec 2024 08:13:33 -0300 Subject: [PATCH 125/186] Add IDLLongArray and some improvements --- .../main/java/idl/helper/IDLLongArray.java | 24 +++++++++ jParser/base/src/main/resources/IDLHelper.h | 54 ++++++++++--------- jParser/base/src/main/resources/IDLHelper.idl | 11 ++++ .../xpenatan/jparser/idl/IDLConstructor.java | 3 ++ .../xpenatan/jparser/idl/IDLHelper.java | 6 +++ .../xpenatan/jparser/idl/IDLMethod.java | 3 ++ .../xpenatan/jparser/idl/IDLParameter.java | 2 + 7 files changed, 79 insertions(+), 24 deletions(-) create mode 100644 jParser/base/src/main/java/idl/helper/IDLLongArray.java diff --git a/jParser/base/src/main/java/idl/helper/IDLLongArray.java b/jParser/base/src/main/java/idl/helper/IDLLongArray.java new file mode 100644 index 00000000..b64484ff --- /dev/null +++ b/jParser/base/src/main/java/idl/helper/IDLLongArray.java @@ -0,0 +1,24 @@ +package idl.helper; + +import idl.IDLBase; + +public class IDLLongArray extends IDLBase { + + public IDLLongArray(int size) { + } + + public void copy(long[] array) { + int length = array.length; + resize(length); + for(int i = 0; i < length; i++) { + long value = array[i]; + setValue(i, value); + } + } + + public native void setValue(int index, long value); + public native void resize(int size); + public native long getValue(int index); + public native long getPointer(); + public native int getSize(); +} \ No newline at end of file diff --git a/jParser/base/src/main/resources/IDLHelper.h b/jParser/base/src/main/resources/IDLHelper.h index 3aea32a3..d7d3b498 100644 --- a/jParser/base/src/main/resources/IDLHelper.h +++ b/jParser/base/src/main/resources/IDLHelper.h @@ -4,6 +4,8 @@ #include #include // NULL #include // intptr_t +#include +#include template class IDLArray { @@ -11,39 +13,42 @@ class IDLArray { int size; T* data; - void deleteData() { delete[] data; data = NULL; } + void deleteData() { delete[] data; data = nullptr; } public: - IDLArray(int size) { data = NULL; resize(size); } - ~IDLArray() { if(data != NULL) { deleteData(); } } + IDLArray(int size) : size(0), data(nullptr) { resize(size); } + ~IDLArray() { deleteData(); } void resize(int newSize) { - if(this->data != NULL) { - deleteData(); + if(newSize > 0 && size != newSize) { + T* newData = new T[newSize]; + if (data != nullptr) { + deleteData(); // Delete the old array + } + data = newData; // Update the data pointer + size = newSize; // Update the size + clear(); } - T * newData = new T[newSize]; - this->data = newData; - size = newSize; - clear(); } void clear() { - for(int i = 0; i < size; i++) { - data[i] = 0; - } + std::fill(data, data + size, T()); } void copy(IDLArray& src, int srcPos, int destPos, int length) { - T* dest = data; - int srcP = srcPos; - int destP = destPos; - int count = 0; - while(count < length) { - T srcByte = src.getValue(srcP); - srcP++; - dest[destP] = srcByte; - destP++; - count++; + if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.size || destPos + length > size) { + throw std::out_of_range("Invalid copy range"); + } + std::copy(src.data + srcPos, src.data + srcPos + length, data + destPos); + } + T getValue(int index) { + if (index < 0 || index >= size) { + throw std::out_of_range("Index out of range"); + } + return data[index]; + } + void setValue(int index, T value) { + if (index < 0 || index >= size) { + throw std::out_of_range("Index out of range"); } + data[index] = value; } - T getValue(int index) { return data[index]; } - void setValue(int index, T value) { data[index] = value; } int getSize() { return size; } void* getPointer() { return (void*)data; } T* getData() { return data; } @@ -53,6 +58,7 @@ typedef std::string IDLString; typedef std::string_view IDLStringView; typedef IDLArray IDLBoolArray; typedef IDLArray IDLIntArray; +typedef IDLArray IDLLongArray; typedef IDLArray IDLFloatArray; typedef IDLArray IDLDoubleArray; typedef IDLArray IDLByteArray; \ No newline at end of file diff --git a/jParser/base/src/main/resources/IDLHelper.idl b/jParser/base/src/main/resources/IDLHelper.idl index 73db12f7..02512673 100644 --- a/jParser/base/src/main/resources/IDLHelper.idl +++ b/jParser/base/src/main/resources/IDLHelper.idl @@ -40,6 +40,17 @@ interface IDLIntArray { void copy([Ref] IDLIntArray src, long srcOffset, long destOffset, long length); }; +interface IDLLongArray { + void IDLLongArray(long size); + void resize(long size); + void clear(); + long long getValue(long index); + void setValue(long index, long long value); + long getSize(); + any getPointer(); + void copy([Ref] IDLLongArray src, long srcOffset, long destOffset, long length); +}; + interface IDLFloatArray { void IDLFloatArray(long size); void resize(long size); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLConstructor.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLConstructor.java index 5e9ba02d..93ce848c 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLConstructor.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLConstructor.java @@ -22,6 +22,9 @@ public IDLConstructor(IDLFile idlFile, IDLClass idlClass) { public void initConstructor(String line) { this.line = line; paramsLine = IDLMethod.setParameters(idlFile, line, parameters); + for(IDLParameter parameter : parameters) { + parameter.idlConstructor = this; + } } public int getTotalOptionalParams() { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLHelper.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLHelper.java index eb14af92..adb840ee 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLHelper.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLHelper.java @@ -24,6 +24,9 @@ public static String getCArray(String type) { else if(type.equals("IDLIntArray")) { return "int *"; } + else if(type.equals("IDLLongArray")) { + return "long long *"; + } else if(type.equals("IDLFloatArray")) { return "float *"; } @@ -165,6 +168,9 @@ public static String getIDLArrayOrNull(String type) { if(type.equals("int[]")) { type = "IDLIntArray"; } + else if(type.equals("long[]") || type.equals("long long[]")) { + type = "IDLLongArray"; + } else if(type.equals("float[]")) { type = "IDLFloatArray"; } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java index 06b9080d..42752b5b 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java @@ -32,6 +32,9 @@ public IDLMethod(IDLClass idlClass, IDLFile idlFile) { public void initMethod(String line) { this.line = line; paramsLine = IDLMethod.setParameters(idlFile, line, parameters); + for(IDLParameter parameter : parameters) { + parameter.idlMethod = this; + } int index = line.indexOf("("); String leftSide = line.substring(0, index).trim(); leftSide = IDLHelper.removeMultipleSpaces(leftSide.trim()); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java index 2ad418b5..63098b1d 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java @@ -7,6 +7,8 @@ */ public class IDLParameter { public final IDLFile idlFile; + public IDLMethod idlMethod; + public IDLConstructor idlConstructor; public String line; public String idlType; From f3ab0916fcda843f7ba59cbcb65726148e0a6de9 Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 9 Dec 2024 18:08:01 -0300 Subject: [PATCH 126/186] user assert instead --- jParser/base/src/main/resources/IDLHelper.h | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/jParser/base/src/main/resources/IDLHelper.h b/jParser/base/src/main/resources/IDLHelper.h index d7d3b498..9c76a6fe 100644 --- a/jParser/base/src/main/resources/IDLHelper.h +++ b/jParser/base/src/main/resources/IDLHelper.h @@ -5,7 +5,7 @@ #include // NULL #include // intptr_t #include -#include +#include template class IDLArray { @@ -32,21 +32,15 @@ class IDLArray { std::fill(data, data + size, T()); } void copy(IDLArray& src, int srcPos, int destPos, int length) { - if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.size || destPos + length > size) { - throw std::out_of_range("Invalid copy range"); - } + assert(srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.size || destPos + length > size); std::copy(src.data + srcPos, src.data + srcPos + length, data + destPos); } T getValue(int index) { - if (index < 0 || index >= size) { - throw std::out_of_range("Index out of range"); - } + assert(index < 0 || index >= size); return data[index]; } void setValue(int index, T value) { - if (index < 0 || index >= size) { - throw std::out_of_range("Index out of range"); - } + assert(index < 0 || index >= size); data[index] = value; } int getSize() { return size; } From df37df0b328a8d52738a9cfb04127663ac79ed61 Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 9 Dec 2024 19:16:03 -0300 Subject: [PATCH 127/186] fix assert --- jParser/base/src/main/resources/IDLHelper.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jParser/base/src/main/resources/IDLHelper.h b/jParser/base/src/main/resources/IDLHelper.h index 9c76a6fe..b7453cbb 100644 --- a/jParser/base/src/main/resources/IDLHelper.h +++ b/jParser/base/src/main/resources/IDLHelper.h @@ -32,15 +32,15 @@ class IDLArray { std::fill(data, data + size, T()); } void copy(IDLArray& src, int srcPos, int destPos, int length) { - assert(srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.size || destPos + length > size); + assert(!(srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.size || destPos + length > size)); std::copy(src.data + srcPos, src.data + srcPos + length, data + destPos); } T getValue(int index) { - assert(index < 0 || index >= size); + assert(!(index < 0 || index >= size)); return data[index]; } void setValue(int index, T value) { - assert(index < 0 || index >= size); + assert(!(index < 0 || index >= size)); data[index] = value; } int getSize() { return size; } From 3a5d5bf53f680b65f161d12a925adf809091c753 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 10 Dec 2024 07:26:04 -0300 Subject: [PATCH 128/186] Add IDLLong class --- .../src/main/java/idl/helper/IDLLong.java | 39 +++++++++++ .../src/main/java/idl/helper/IDLLong2.java | 45 +++++++++++++ .../src/main/java/idl/helper/IDLLong3.java | 55 ++++++++++++++++ .../src/main/java/idl/helper/IDLLong4.java | 65 +++++++++++++++++++ 4 files changed, 204 insertions(+) create mode 100644 jParser/base/src/main/java/idl/helper/IDLLong.java create mode 100644 jParser/base/src/main/java/idl/helper/IDLLong2.java create mode 100644 jParser/base/src/main/java/idl/helper/IDLLong3.java create mode 100644 jParser/base/src/main/java/idl/helper/IDLLong4.java diff --git a/jParser/base/src/main/java/idl/helper/IDLLong.java b/jParser/base/src/main/java/idl/helper/IDLLong.java new file mode 100644 index 00000000..a5d4696f --- /dev/null +++ b/jParser/base/src/main/java/idl/helper/IDLLong.java @@ -0,0 +1,39 @@ +package idl.helper; + +public class IDLLong extends IDLLongArray { + + public static IDLLong TMP_1 = new IDLLong(); + public static IDLLong TMP_2 = new IDLLong(); + public static IDLLong TMP_3 = new IDLLong(); + public static IDLLong TMP_4 = new IDLLong(); + + public static void disposeTEMP() { + TMP_1.dispose(); + TMP_2.dispose(); + TMP_3.dispose(); + TMP_4.dispose(); + } + + public IDLLong() { + super(1); + } + + public IDLLong(int value) { + this(); + set(value); + } + + public IDLLong set(long value) { + setValue(0, value); + return this; + } + + public long getValue() { + return getValue(0); + } + + @Override + public String toString() { + return String.valueOf(getValue()); + } +} \ No newline at end of file diff --git a/jParser/base/src/main/java/idl/helper/IDLLong2.java b/jParser/base/src/main/java/idl/helper/IDLLong2.java new file mode 100644 index 00000000..cae3f588 --- /dev/null +++ b/jParser/base/src/main/java/idl/helper/IDLLong2.java @@ -0,0 +1,45 @@ +package idl.helper; + +public class IDLLong2 extends IDLLongArray { + + public static IDLLong2 TMP_1 = new IDLLong2(); + public static IDLLong2 TMP_2 = new IDLLong2(); + + public static void disposeTEMP() { + TMP_1.dispose(); + TMP_2.dispose(); + } + + public IDLLong2() { + super(2); + } + + public IDLLong2 set(long value0, long value1) { + setValue(0, value0); + setValue(1, value1); + return this; + } + + public IDLLong2 set0(long value) { + setValue(0, value); + return this; + } + + public IDLLong2 set1(long value) { + setValue(1, value); + return this; + } + + public long get0() { + return getValue(0); + } + + public long get1() { + return getValue(1); + } + + @Override + public String toString() { + return get0() + ", " + get1(); + } +} \ No newline at end of file diff --git a/jParser/base/src/main/java/idl/helper/IDLLong3.java b/jParser/base/src/main/java/idl/helper/IDLLong3.java new file mode 100644 index 00000000..4c21b89d --- /dev/null +++ b/jParser/base/src/main/java/idl/helper/IDLLong3.java @@ -0,0 +1,55 @@ +package idl.helper; + +public class IDLLong3 extends IDLLongArray { + + public static IDLLong3 TMP_1 = new IDLLong3(); + public static IDLLong3 TMP_2 = new IDLLong3(); + + public static void disposeTEMP() { + TMP_1.dispose(); + TMP_2.dispose(); + } + + public IDLLong3() { + super(3); + } + + public IDLLong3 set(long value0, long value1, long value2) { + setValue(0, value0); + setValue(1, value1); + setValue(2, value2); + return this; + } + + public IDLLong3 set0(long value) { + setValue(0, value); + return this; + } + + public IDLLong3 set1(long value) { + setValue(1, value); + return this; + } + + public IDLLong3 set2(long value) { + setValue(2, value); + return this; + } + + public long get0() { + return getValue(0); + } + + public long get1() { + return getValue(1); + } + + public long get2() { + return getValue(2); + } + + @Override + public String toString() { + return get0() + ", " + get1() + ", " + get2(); + } +} \ No newline at end of file diff --git a/jParser/base/src/main/java/idl/helper/IDLLong4.java b/jParser/base/src/main/java/idl/helper/IDLLong4.java new file mode 100644 index 00000000..4a96a709 --- /dev/null +++ b/jParser/base/src/main/java/idl/helper/IDLLong4.java @@ -0,0 +1,65 @@ +package idl.helper; + +public class IDLLong4 extends IDLLongArray { + + public static IDLLong4 TMP_1 = new IDLLong4(); + public static IDLLong4 TMP_2 = new IDLLong4(); + + public static void disposeTEMP() { + TMP_1.dispose(); + TMP_2.dispose(); + } + + public IDLLong4() { + super(4); + } + + public IDLLong4 set(long value0, long value1, long value2, long value3) { + setValue(0, value0); + setValue(1, value1); + setValue(2, value2); + setValue(3, value3); + return this; + } + + public IDLLong4 set0(long value) { + setValue(0, value); + return this; + } + + public IDLLong4 set1(long value) { + setValue(1, value); + return this; + } + + public IDLLong4 set2(long value) { + setValue(2, value); + return this; + } + + public IDLLong4 set3(long value) { + setValue(3, value); + return this; + } + + public long get0() { + return getValue(0); + } + + public long get1() { + return getValue(1); + } + + public long get2() { + return getValue(2); + } + + public long get3() { + return getValue(3); + } + + @Override + public String toString() { + return get0() + ", " + get1() + ", " + get2() + ", " + get3(); + } +} \ No newline at end of file From b9395c53a5a1830a6a45853899d7724c2c3523f5 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 10 Dec 2024 07:51:19 -0300 Subject: [PATCH 129/186] update readme --- README.md | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 52a48ddc..b96b7680 100644 --- a/README.md +++ b/README.md @@ -5,25 +5,28 @@ [![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/releases/com.github.xpenatan.jParser/jParser-core?nexusVersion=2&server=https%3A%2F%2Foss.sonatype.org&label=release)](https://repo.maven.apache.org/maven2/com/github/xpenatan/jParser/) [![Static Badge](https://img.shields.io/badge/snapshot---SNAPSHOT-red)](https://oss.sonatype.org/content/repositories/snapshots/com/github/xpenatan/jParser/) -jParser is a small Java library that helps bind C/C++ code to desktop, mobile, and the web, allowing it to be written inline with Java source code. +jParser is a compact Java library designed to facilitate the integration of C/C++ code with desktop, mobile, and web platforms, enabling inline writing within Java source code. -It was inspired by [gdx-jnigen](https://github.com/libgdx/gdx-jnigen) that you add a native code into a code block. This code block will be translated to the specific code target. You can add multiple code block targets in the same java source. For each code target, it will generate a new java source code. +Inspired by [gdx-jnigen](https://github.com/libgdx/gdx-jnigen), jParser allows you to embed native code within a code block. This block is then translated into the appropriate target-specific code. You can define multiple code block targets within the same Java source file, and for each target, jParser generates a corresponding Java source file. -For the web, it needs emscripten to generate a js/wasm file and [teavm](https://github.com/konsoletyper/teavm). The generated classes in teavm module use JSBody to communicate with javascript. +For web applications, jParser requires Emscripten to produce JS/WASM files and utilizes [TeaVM](https://github.com/konsoletyper/teavm). The classes generated in the TeaVM module use `JSBody` annotation solution to interact with JavaScript. -jParser only supports ```JNI``` and ```TEAVM``` code targets. +Currently, jParser supports only `JNI` and `TEAVM` code targets. -### How it works -jParser has two part. -* Read the java source code containing the jParser solution and generate a new java source code for each target. We use base module for this. For desktop/mobile the generated JNI code will be at ```core module``` and the web code will be inside ```teavm module```. -* Compile C/C++ for each platform (Windows/Linux/MacOS/Android/iOS/Web). +### How it Works +jParser consists of two main components: + +1. **Code Generation**: It reads the Java source code containing the jParser solution and generates new Java source code for each target platform. The `base` module is used for this purpose. For desktop and mobile platforms, the generated JNI code is located in the `core` module, while the web-specific code is placed in the `teavm` module. + +2. **C/C++ Compilation**: It compiles the C/C++ code for various platforms, including Windows, Linux, macOS, Android, iOS, and the Web. ## WebIDL -To improve even more the long hours of porting each method manually, jParser also has Emscripten WebIDL support. You create a webidl file, and it will generate binding code for JNI and teaVM. -It's not 100%, but it will reduce the amount of work binding big libraries. You can check the example:lib module or gdx-imgui for a complete example. +To further streamline the lengthy process of manually porting each method, jParser includes support for Emscripten WebIDL. By creating a WebIDL file, you can automatically generate binding code for both JNI and TeaVM. While this feature may not cover every scenario, it significantly reduces the effort required to bind large libraries. For a comprehensive example, refer to the `example:lib` module or `gdx-imgui`. -It will create the exact same method as the webidl file. If C++ is case-sensitive as in ImGui, the Java methods will be also case-sensitive.
-C/C++ attributes are converted to methods, it starts with 'set_' or 'get_'. +The generated methods will match those defined in the WebIDL file. If the C++ code is case-sensitive, as seen in ImGui, the corresponding Java methods will also maintain case sensitivity. Additionally, C/C++ attributes are converted into methods prefixed with `set_` or `get_`. + +## WebIDL Classes +IDL classes, such as `IDLInt` or `IDLIntArray`, provide a method for passing primitive pointers to C++ code, compatible with Emscripten, desktop, and mobile platforms. Use these classes when you need to pass a pointer array or a primitive that the C++ code will modify. Libraries usisng jParser:
- [gdx-imgui](https://github.com/xpenatan/gdx-imgui) @@ -34,5 +37,6 @@ Libraries usisng jParser:
- [gdx-box2d](https://github.com/xpenatan/gdx-box2d) ## Requirements: -#### [mingw64](https://github.com/niXman/mingw-builds-binaries/releases) -#### [emscripten](https://emscripten.org/) +#### [Mingw64](https://github.com/niXman/mingw-builds-binaries/releases) or [Visual Studio C++](https://visualstudio.microsoft.com/vs/community/) +#### [Emscripten](https://emscripten.org/) + From 9f1202c87e9239af2eafff216dddb59b653b13bd Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 15 Feb 2025 16:35:09 -0300 Subject: [PATCH 130/186] update gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5c487971..c97ec5d4 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ out/ **/lib/lib-teavm/src/main/java/** **/lib/lib-core/src/main/java/** **/app/android/libs/ +.codiumai \ No newline at end of file From 3a1ad111b2cc3b4f7eed2c4d6a7ab4f44f17bd92 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 16 Feb 2025 22:11:04 -0300 Subject: [PATCH 131/186] Make callback abstract and with protected methods --- .../github/xpenatan/jparser/cpp/CppCodeParser.java | 12 ++++++------ .../com/github/xpenatan/jparser/idl/IDLClass.java | 3 ++- .../xpenatan/jparser/idl/IDLClassOrEnum.java | 5 +++++ .../com/github/xpenatan/jparser/idl/IDLReader.java | 5 +++-- .../jparser/idl/parser/IDLCallbackParser.java | 6 ++++-- .../idl/parser/IDLClassGeneratorParser.java | 14 ++++++++++---- .../jparser/idl/parser/IDLConstructorParser.java | 2 +- .../jparser/idl/parser/IDLDefaultCodeParser.java | 2 +- .../xpenatan/jparser/teavm/TeaVMCodeParser.java | 4 ++-- 9 files changed, 34 insertions(+), 19 deletions(-) diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index f471f3c1..1381fd7a 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -221,11 +221,11 @@ public void onIDLConstructorGenerated(JParser jParser, IDLConstructor idlConstru public void onIDLDeConstructorGenerated(JParser jParser, IDLClass idlClass, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration nativeMethodDeclaration) { String classTypeName; - if(idlClass.callback == null) { + if(idlClass.callbackImpl == null) { classTypeName = idlClass.classHeader.prefixName + classDeclaration.getNameAsString(); } else { - classTypeName = idlClass.callback.name; + classTypeName = idlClass.callbackImpl.name; } String content = METHOD_DELETE_OBJ_POINTER_TEMPLATE.replace(TEMPLATE_TAG_TYPE, classTypeName); @@ -395,7 +395,7 @@ public void onIDLEnumMethodGenerated(JParser jParser, IDLEnum idlEnum, ClassOrIn @Override public void onIDLCallbackGenerated(JParser jParser, IDLClass idlClass, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration callbackDeclaration, ArrayList>> methods) { NodeList methodParameters = callbackDeclaration.getParameters(); - IDLClass idlCallbackClass = idlClass.callback; + IDLClass idlCallbackClass = idlClass.callbackImpl; Type methodReturnType = callbackDeclaration.getType(); MethodDeclaration nativeMethodDeclaration = IDLMethodParser.generateNativeMethod(callbackDeclaration.getNameAsString(), methodParameters, methodReturnType, false); if(!JParserHelper.containsMethod(classDeclaration, nativeMethodDeclaration)) { @@ -420,7 +420,7 @@ public void onIDLCallbackGenerated(JParser jParser, IDLClass idlClass, ClassOrIn private void generateCPPClass(IDLClass idlClass, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration callbackDeclaration, ArrayList>> methods) { - IDLClass callback = idlClass.callback; + IDLClass callback = idlClass.callbackImpl; String cppClass = ""; String callbackCode = generateSetupCallbackMethod(idlClass, callbackDeclaration, methods); @@ -456,7 +456,7 @@ private String generateSetupCallbackMethod(IDLClass idlClass, MethodDeclaration String variableTemplate = "\tinline static jmethodID [METHOD]_ID = 0;\n"; String methodIdTemplate = "\t\t[CLASS_NAME]::[METHOD]_ID = env->GetMethodID(jClassID, \"[INTERNAL_METHOD]\", \"[PARAM_CODE]\");\n"; - IDLClass callbackClass = idlClass.callback; + IDLClass callbackClass = idlClass.callbackImpl; String className = callbackClass.name; String staticVariables = ""; @@ -535,7 +535,7 @@ else if(type.isClassOrInterfaceType()) { } private String generateMethodCallers(IDLClass idlClass, ArrayList>> methods) { - IDLClass callback = idlClass.callback; + IDLClass callback = idlClass.callbackImpl; String cppMethods = ""; String cppClassName = callback.name; diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java index d3f52194..72b5c502 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java @@ -17,7 +17,8 @@ public class IDLClass extends IDLClassOrEnum { public final ArrayList attributes = new ArrayList<>(); public ArrayList settings = new ArrayList<>(); - public IDLClass callback; + public boolean isCallback; + public IDLClass callbackImpl; public boolean idlSkip = false; public IDLClass(IDLFile idlFile) { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClassOrEnum.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClassOrEnum.java index 84069b7d..cf1995d5 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClassOrEnum.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClassOrEnum.java @@ -22,4 +22,9 @@ public IDLClass asClass() { public IDLEnum asEnum() { return (IDLEnum)this; } + + @Override + public String toString() { + return name; + } } \ No newline at end of file diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java index c7732b56..994be339 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java @@ -217,8 +217,9 @@ private static void configCallbacks(IDLFile idlFile, ArrayList c if(!jsImplementation.isEmpty()) { IDLClass callbackClass = idlFile.getClass(jsImplementation); if(callbackClass != null) { - if(callbackClass.callback == null) { - callbackClass.callback = idlCallbackImpl; + if(callbackClass.callbackImpl == null) { + callbackClass.callbackImpl = idlCallbackImpl; + callbackClass.isCallback = true; } else { throw new RuntimeException("Class " + callbackClass.name + " cannot have multiple JSImplementation"); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java index e0ab3355..fbd0b683 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLCallbackParser.java @@ -25,7 +25,7 @@ public class IDLCallbackParser { private final static String callbackMethodName = "setupCallback"; public static void generateCallback(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classDeclaration, IDLClass idlClass) { - ArrayList constructors = idlClass.callback.constructors; + ArrayList constructors = idlClass.callbackImpl.constructors; if(constructors.size() == 1) { IDLConstructor idlConstructor = constructors.get(0); ConstructorDeclaration constructorDeclaration = IDLConstructorParser.getOrCreateConstructorDeclaration(idlParser, jParser, unit, classDeclaration, idlConstructor); @@ -51,11 +51,13 @@ public static void generateCallback(IDLDefaultCodeParser idlParser, JParser jPar private static ArrayList>> createCallbackMethods(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classDeclaration, IDLClass idlClass) { ArrayList>> methods = new ArrayList<>(); - IDLClass callbackClass = idlClass.callback; + IDLClass callbackClass = idlClass.callbackImpl; for(IDLMethod method : callbackClass.methods) { MethodDeclaration methodDeclaration = IDLMethodParser.generateAndAddMethodOnly(idlParser, jParser, unit, classDeclaration, method); MethodDeclaration internalMethod = methodDeclaration.clone(); + methodDeclaration.removeModifier(Modifier.Keyword.PUBLIC); + methodDeclaration.addModifier(Modifier.Keyword.PROTECTED); internalMethod.removeModifier(Modifier.Keyword.PUBLIC); internalMethod.addModifier(Modifier.Keyword.PRIVATE); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java index eabea4de..ad2ad053 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java @@ -189,10 +189,16 @@ private CompilationUnit setupClass(IDLClassOrEnum idlClass, String subPackage) { classDeclaration.setPublic(true); if(idlClass.isClass()) { - // For every class we generate empty object that can be used when needed. - IDLMethodParser.generateFieldName("T_01", classDeclaration, className, true, Modifier.Keyword.PUBLIC, true); - IDLMethodParser.generateFieldName("T_02", classDeclaration, className, true, Modifier.Keyword.PUBLIC, true); - IDLMethodParser.generateFieldName("T_03", classDeclaration, className, true, Modifier.Keyword.PUBLIC, true); + IDLClass aClass = idlClass.asClass(); + if(aClass.isCallback) { + classDeclaration.setAbstract(true); + } + else { + // For every class we generate empty object that can be used when needed. + IDLMethodParser.generateFieldName("T_01", classDeclaration, className, true, Modifier.Keyword.PUBLIC, true); + IDLMethodParser.generateFieldName("T_02", classDeclaration, className, true, Modifier.Keyword.PUBLIC, true); + IDLMethodParser.generateFieldName("T_03", classDeclaration, className, true, Modifier.Keyword.PUBLIC, true); + } } // Hack to inject internal dependencies return StaticJavaParser.parse(compilationUnit.toString()); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java index e010e931..125f34dd 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java @@ -26,7 +26,7 @@ public class IDLConstructorParser { public static void generateConstructor(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classOrInterfaceDeclaration, IDLClass idlClass) { ArrayList constructors = idlClass.constructors; - if(idlClass.callback == null) { + if(idlClass.callbackImpl == null) { // Generate constructors only if it's not callback for(int i = 0; i < constructors.size(); i++) { IDLConstructor idlConstructor = constructors.get(i); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java index d735293b..922e18f8 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java @@ -107,7 +107,7 @@ public void onParseClassStart(JParser jParser, CompilationUnit unit, ClassOrInte } if(generateClass) { - if(idlClass.callback != null) { + if(idlClass.callbackImpl != null) { IDLCallbackParser.generateCallback(this, jParser, unit, classOrInterfaceDeclaration, idlClass); } diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index 94b62db0..55fe223b 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -302,11 +302,11 @@ public void onIDLConstructorGenerated(JParser jParser, IDLConstructor idlConstru @Override public void onIDLDeConstructorGenerated(JParser jParser, IDLClass idlClass, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration nativeMethodDeclaration) { String returnTypeName ; - if(idlClass.callback == null) { + if(idlClass.callbackImpl == null) { returnTypeName = classDeclaration.getNameAsString(); } else { - returnTypeName = idlClass.callback.name; + returnTypeName = idlClass.callbackImpl.name; } String content = METHOD_DELETE_OBJ_POINTER_TEMPLATE.replace(TEMPLATE_TAG_MODULE, module).replace(TEMPLATE_TAG_TYPE, returnTypeName); From a96d9d96eed03eef6e62f7da4949d33011e11771 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 16 Feb 2025 22:49:14 -0300 Subject: [PATCH 132/186] Remove abstract from callback to fix some internal use solution --- .../xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java index ad2ad053..eb941446 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java @@ -191,7 +191,7 @@ private CompilationUnit setupClass(IDLClassOrEnum idlClass, String subPackage) { if(idlClass.isClass()) { IDLClass aClass = idlClass.asClass(); if(aClass.isCallback) { - classDeclaration.setAbstract(true); + // Do nothing } else { // For every class we generate empty object that can be used when needed. From 0f0d4bd8c9f0b674d94f9536534ea8c79051926b Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 22 Feb 2025 16:21:36 -0300 Subject: [PATCH 133/186] Improvements to use the source directly instead of copying it to build folder --- build.gradle.kts | 4 +- buildSrc/src/main/kotlin/Dependencies.kt | 4 +- example/app/android/build.gradle.kts | 2 +- example/lib/lib-android/build.gradle.kts | 4 +- .../main/cpp/source/TestLib/src/TestLib.cpp | 1 + .../lib/lib-build/src/main/java/BuildLib.java | 73 ++++++++++--------- gradle/wrapper/gradle-wrapper.properties | 2 +- .../jparser/builder/tool/BuilderTool.java | 22 +----- .../xpenatan/jparser/builder/BuildConfig.java | 26 +++++-- .../jparser/builder/DefaultBuildTarget.java | 10 +-- .../xpenatan/jparser/builder/JBuilder.java | 2 +- .../builder/targets/AndroidTarget.java | 2 +- .../builder/targets/EmscriptenLibTarget.java | 2 +- .../builder/targets/EmscriptenTarget.java | 2 +- .../builder/tool/BuildToolOptions.java | 37 ++++++---- .../jparser/cpp/NativeCPPGenerator.java | 8 +- 16 files changed, 104 insertions(+), 97 deletions(-) create mode 100644 example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.cpp rename jParser/{builder-tool => builder}/src/main/java/com/github/xpenatan/jparser/builder/tool/BuildToolOptions.java (85%) diff --git a/build.gradle.kts b/build.gradle.kts index c69762e5..52ef4af3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,10 +11,10 @@ buildscript { google() } - val kotlinVersion = "1.8.10" + val kotlinVersion = "2.1.10" dependencies { - classpath("com.android.tools.build:gradle:7.3.1") + classpath("com.android.tools.build:gradle:8.2.0") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") } } diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index d52ed76d..852aa44c 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -8,8 +8,8 @@ object LibExt { const val jUnitVersion = "4.13.2" const val groupId = "com.github.xpenatan.jParser" const val exampleUseRepoLibs = false - const val gdxVersion = "1.12.1" - const val teaVMVersion = "0.10.0" + const val gdxVersion = "1.13.1" + const val teaVMVersion = "0.11.0" const val gdxTeaVMVersion = "-SNAPSHOT" } diff --git a/example/app/android/build.gradle.kts b/example/app/android/build.gradle.kts index a6e85c47..d5949da8 100644 --- a/example/app/android/build.gradle.kts +++ b/example/app/android/build.gradle.kts @@ -7,7 +7,7 @@ group = "jparser.app.android" android { namespace = "com.example.myapplication" - compileSdk = 33 + compileSdk = 34 defaultConfig { applicationId = "com.example.myapplication" diff --git a/example/lib/lib-android/build.gradle.kts b/example/lib/lib-android/build.gradle.kts index a407ceac..377325f7 100644 --- a/example/lib/lib-android/build.gradle.kts +++ b/example/lib/lib-android/build.gradle.kts @@ -7,7 +7,7 @@ group = "jparser.lib.android" android { namespace = "com.github.xpenatan.jparser.example.testlib" - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 21 @@ -15,7 +15,7 @@ android { sourceSets { named("main") { - jniLibs.srcDirs("$projectDir/../generator/build/c++/libs/android") + jniLibs.srcDirs("$projectDir/../lib-build/build/c++/libs/android") } } compileOptions { diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.cpp b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.cpp new file mode 100644 index 00000000..a9f6cae6 --- /dev/null +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.cpp @@ -0,0 +1 @@ +#include "TestLib.h" \ No newline at end of file diff --git a/example/lib/lib-build/src/main/java/BuildLib.java b/example/lib/lib-build/src/main/java/BuildLib.java index eba7c2f9..71c5f3db 100644 --- a/example/lib/lib-build/src/main/java/BuildLib.java +++ b/example/lib/lib-build/src/main/java/BuildLib.java @@ -9,7 +9,6 @@ import com.github.xpenatan.jparser.builder.tool.BuildToolListener; import com.github.xpenatan.jparser.builder.tool.BuildToolOptions; import com.github.xpenatan.jparser.builder.tool.BuilderTool; -import com.github.xpenatan.jparser.cpp.NativeCPPGenerator; import com.github.xpenatan.jparser.idl.IDLReader; import java.util.ArrayList; @@ -56,65 +55,67 @@ public void onAddTarget(BuildToolOptions op, IDLReader idlReader, ArrayList additionalSourceDirs = new ArrayList<>(); - public CustomFileDescriptor libDir; - public String libName; - - public BuildConfig(String sourceDir, String buildDir, String libsDir, String libName) { - this.sourceDir = new CustomFileDescriptor(sourceDir); + public final CustomFileDescriptor buildDir; + public final CustomFileDescriptor buildSourceDir; + public final ArrayList additionalSourceDirs = new ArrayList<>(); + public final CustomFileDescriptor libDir; + public final String libName; + private final BuildToolOptions op; + + public BuildConfig(BuildToolOptions op) { + this.op = op; + String buildSourceDir = op.getCPPDestinationPath(); + String buildDir = op.getModuleBuildCPPPath(); + String libsDir = op.getLibsDir(); + String libName = op.libName; + String sourcePath = op.getSourceDir(); + this.buildDir = new CustomFileDescriptor(buildDir); + this.buildSourceDir = new CustomFileDescriptor(buildSourceDir); + additionalSourceDirs.add(new CustomFileDescriptor(sourcePath)); this.libDir = new CustomFileDescriptor(libsDir); this.libName = libName; diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java index 140808d6..2e794e91 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java @@ -58,7 +58,7 @@ protected boolean buildInternal(BuildConfig config) { } childTarget.mkdirs(); - idlDir = config.sourceDir.child("idl"); + idlDir = config.buildSourceDir.child("idl"); if(!idlDir.exists()) { idlDir.mkdirs(); } @@ -75,7 +75,7 @@ protected boolean buildInternal(BuildConfig config) { protected void setup(BuildConfig config) {} protected boolean build(BuildConfig config, CustomFileDescriptor buildTargetTemp) { - ArrayList cppFiles = new ArrayList<>(getCPPFiles(config.sourceDir, cppInclude, cppExclude, filterCPPSuffix)); + ArrayList cppFiles = getCPPFiles(config.buildSourceDir, cppInclude, cppExclude, filterCPPSuffix); for(CustomFileDescriptor sourceDir : config.additionalSourceDirs) { ArrayList cppFiles1 = getCPPFiles(sourceDir, cppInclude, cppExclude, filterCPPSuffix); cppFiles.addAll(cppFiles1); @@ -107,7 +107,7 @@ protected boolean compile(BuildConfig config, CustomFileDescriptor buildTargetTe cppList.writeString(compiledPaths.trim(), false); if(multiCoreCompile) { - System.err.println("##### COMPILE #####"); + System.out.println("##### COMPILE #####"); int threads = Runtime.getRuntime().availableProcessors(); ExecutorService executorService = Executors.newFixedThreadPool(threads); @@ -158,7 +158,7 @@ protected boolean compile(BuildConfig config, CustomFileDescriptor buildTargetTe compilerCommands.addAll(cppFlags); compilerCommands.addAll(headerDirs); compilerCommands.add("@" + cppList.path()); - System.err.println("##### COMPILE #####"); + System.out.println("##### COMPILE #####"); boolean flag = JProcess.startProcess(config.buildDir.file(), compilerCommands); if(!flag) { return false; @@ -204,7 +204,7 @@ private boolean link(BuildConfig config, CustomFileDescriptor childTarget) { linkerCommands.clear(); onLink(compiledObjects, objList.path(), libPath); - System.err.println("##### LINK #####"); + System.out.println("##### LINK #####"); return JProcess.startProcess(childTarget.file(), linkerCommands); } diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/JBuilder.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/JBuilder.java index c00f228a..97394e44 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/JBuilder.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/JBuilder.java @@ -16,7 +16,7 @@ public static void build(BuildConfig config, BuildMultiTarget ... targets) { if(target != null) { for(BuildTarget buildTarget : target.multiTarget) { String targetName = buildTarget.getClass().getSimpleName(); - System.err.println("##### Building: " + targetName + " #####"); + System.out.println("##### Building: " + targetName + " #####"); if(!buildTarget.buildInternal(config)) { throw new RuntimeException(); } diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java index af92f6a8..e8939d6d 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java @@ -67,7 +67,7 @@ protected boolean build(BuildConfig config, CustomFileDescriptor buildTargetTemp } linkerFlagsStr = linkerFlagsStr.trim(); - ArrayList cppFiles = new ArrayList<>(getCPPFiles(config.sourceDir, cppInclude, cppExclude, filterCPPSuffix)); + ArrayList cppFiles = new ArrayList<>(getCPPFiles(config.buildSourceDir, cppInclude, cppExclude, filterCPPSuffix)); for(CustomFileDescriptor sourceDir : config.additionalSourceDirs) { ArrayList cppFiles1 = getCPPFiles(sourceDir, cppInclude, cppExclude, filterCPPSuffix); cppFiles.addAll(cppFiles1); diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenLibTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenLibTarget.java index d7c6e159..1c93407a 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenLibTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenLibTarget.java @@ -55,7 +55,7 @@ public EmscriptenLibTarget() { @Override protected boolean build(BuildConfig config, CustomFileDescriptor buildTargetTemp) { - CustomFileDescriptor jsglueDir = config.sourceDir.child("jsglue"); + CustomFileDescriptor jsglueDir = config.buildSourceDir.child("jsglue"); if(!jsglueDir.exists()) { jsglueDir.mkdirs(); } diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java index f52ff3ad..8b579645 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java @@ -67,7 +67,7 @@ protected boolean build(BuildConfig config, CustomFileDescriptor buildTargetTemp libName = config.libName; } - CustomFileDescriptor jsglueDir = config.sourceDir.child("jsglue"); + CustomFileDescriptor jsglueDir = config.buildSourceDir.child("jsglue"); if(!jsglueDir.exists()) { jsglueDir.mkdirs(); } diff --git a/jParser/builder-tool/src/main/java/com/github/xpenatan/jparser/builder/tool/BuildToolOptions.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/tool/BuildToolOptions.java similarity index 85% rename from jParser/builder-tool/src/main/java/com/github/xpenatan/jparser/builder/tool/BuildToolOptions.java rename to jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/tool/BuildToolOptions.java index c7a3abd2..672c8f4c 100644 --- a/jParser/builder-tool/src/main/java/com/github/xpenatan/jparser/builder/tool/BuildToolOptions.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/tool/BuildToolOptions.java @@ -1,6 +1,7 @@ package com.github.xpenatan.jparser.builder.tool; import com.github.xpenatan.jparser.builder.BuildTarget; +import com.github.xpenatan.jparser.core.util.CustomFileDescriptor; import java.io.File; import java.io.IOException; @@ -9,7 +10,6 @@ public class BuildToolOptions { public String libName; public String moduleName; public String libBasePackage; - public String buildSourceDir; public boolean generateTeaVM = true; public boolean generateCPP = true; @@ -24,11 +24,10 @@ public class BuildToolOptions { private String moduleTeavmPath; private String idlPath; private String moduleBaseJavaDir; - private String cppSourceDir; + private String sourcePath; private String customSourceDir; private String libsDir; private String cppDestinationPath; - private String libDestinationPath; public final boolean windows64; public final boolean linux64; @@ -43,14 +42,28 @@ public class BuildToolOptions { * @param libName module name * @param libBasePackage module package that all classes will be in * @param modulePrefix module prefix name. ex: imgui. So it will be imgui-core, imgui-teavm, etc. - * @param buildSourceDir path inside lib-build module + * @param cppSourcePath full path where the source is located * @param platform windows64, linux64, mac64, mac64arm, android, ios, teavm */ - public BuildToolOptions(String libName, String libBasePackage, String modulePrefix, String buildSourceDir, String ... platform) { + public BuildToolOptions(String libName, String libBasePackage, String modulePrefix, String cppSourcePath, String ... platform) { this.libName = libName; this.libBasePackage = libBasePackage; this.modulePrefix = modulePrefix; - this.buildSourceDir = buildSourceDir; + + boolean exists = new CustomFileDescriptor(cppSourcePath).exists(); + if(exists) { + this.sourcePath = cppSourcePath.replace("\\", "/"); + } + else { + try { + this.sourcePath = new File(".", cppSourcePath).getCanonicalPath().replace("\\", "/"); + } catch(IOException e) { + throw new RuntimeException(e); + } + } + if(!this.sourcePath.endsWith("/")) { + this.sourcePath += "/"; + } this.idlName = libName; this.moduleName = libName; @@ -109,13 +122,11 @@ void setup() { moduleBaseJavaDir = moduleBasePath + "/src/main/java"; idlPath = moduleBuildPath + "/src/main/cpp/" + idlName + ".idl"; - cppSourceDir = moduleBuildPath + buildSourceDir; - customSourceDir = moduleBuildPath + "/src/main/cpp/custom"; + customSourceDir = moduleBuildPath + "/src/main/cpp/custom/"; moduleBuildCPPPath = moduleBuildPath + "/build/c++"; libsDir = moduleBuildCPPPath + "/libs"; cppDestinationPath = moduleBuildCPPPath + "/src"; - libDestinationPath = cppDestinationPath + "/" + libName; } public String getModulePrefix() { @@ -150,8 +161,8 @@ public String getModuleBaseJavaDir() { return moduleBaseJavaDir; } - public String getCPPSourceDir() { - return cppSourceDir; + public String getSourceDir() { + return sourcePath; } /** @@ -168,8 +179,4 @@ public String getLibsDir() { public String getCPPDestinationPath() { return cppDestinationPath; } - - public String getLibDestinationPath() { - return libDestinationPath; - } } \ No newline at end of file diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/NativeCPPGenerator.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/NativeCPPGenerator.java index b1c80db5..6f025c27 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/NativeCPPGenerator.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/NativeCPPGenerator.java @@ -85,7 +85,7 @@ public class NativeCPPGenerator implements CppGenerator { otherTypes.put("Throwable", ArgumentType.Throwable); } - private String cppDestinationDir; + private String glueCppDestinationDir; private String cppGlueName = "JNIGlue"; StringBuilder mainPrinter = new StringBuilder(); @@ -105,7 +105,7 @@ public NativeCPPGenerator(String cppDestinationDir) { public NativeCPPGenerator(String cppDestinationDir, boolean exportJNIMethods) { try { this.exportJNIMethods = exportJNIMethods; - this.cppDestinationDir = new File(cppDestinationDir).getCanonicalPath() + File.separator; + this.glueCppDestinationDir = new File(cppDestinationDir, "jniglue").getCanonicalPath() + File.separator; } catch(IOException e) { throw new RuntimeException(e); } @@ -258,9 +258,7 @@ public void generate(JParser jParser) { print(PrintType.MAIN, "}"); String code = mainPrinter.toString(); - String gluePathStr = cppDestinationDir + File.separator + ".." + File.separator + "jniglue" + File.separator; - CustomFileDescriptor gluePath = new CustomFileDescriptor(gluePathStr); - + String gluePathStr = glueCppDestinationDir; String cppGlueHPath = gluePathStr + cppGlueName + ".h"; String cppGluePath = gluePathStr + cppGlueName + ".cpp"; CustomFileDescriptor fileDescriptor = new CustomFileDescriptor(cppGlueHPath); From 877320f2b0654c85d2b8db1d98be2ee33b743eb9 Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 22 Feb 2025 16:29:02 -0300 Subject: [PATCH 134/186] Remove android target sdk --- example/app/android/build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/example/app/android/build.gradle.kts b/example/app/android/build.gradle.kts index d5949da8..0f2401d9 100644 --- a/example/app/android/build.gradle.kts +++ b/example/app/android/build.gradle.kts @@ -12,7 +12,6 @@ android { defaultConfig { applicationId = "com.example.myapplication" minSdk = 24 - targetSdk = 33 versionCode = 1 versionName = "1.0" } From 99f23a8dbc845b44ccd7398f070aad59111a8672 Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 22 Feb 2025 16:35:49 -0300 Subject: [PATCH 135/186] update java --- .github/workflows/build_and_upload.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 2a7a1d6c..d51538b4 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -31,7 +31,7 @@ jobs: uses: actions/setup-java@v4 with: distribution: "zulu" - java-version: 11 + java-version: 17 - name: Set up MinGW uses: msys2/setup-msys2@v2 @@ -73,7 +73,7 @@ jobs: uses: actions/setup-java@v4 with: distribution: "zulu" - java-version: 11 + java-version: 17 - name: Set up MinGW run: | @@ -108,7 +108,7 @@ jobs: uses: actions/setup-java@v4 with: distribution: "zulu" - java-version: 11 + java-version: 17 - name: Change wrapper permissions run: chmod +x ./gradlew @@ -140,7 +140,7 @@ jobs: uses: actions/setup-java@v4 with: distribution: "zulu" - java-version: 11 + java-version: 17 - name: Set up MinGW run: | @@ -178,7 +178,7 @@ jobs: uses: actions/setup-java@v4 with: distribution: "zulu" - java-version: 11 + java-version: 17 - name: Set up MinGW run: | @@ -230,7 +230,7 @@ jobs: uses: actions/setup-java@v4 with: distribution: "zulu" - java-version: 11 + java-version: 17 - name: Set up MinGW run: | From ea1adde16393cbf2a2b7a5049e94581b297311fe Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 22 Feb 2025 16:36:32 -0300 Subject: [PATCH 136/186] update java --- .github/workflows/build_and_upload.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index d51538b4..b9072c1c 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -27,7 +27,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v4 with: distribution: "zulu" @@ -69,7 +69,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v4 with: distribution: "zulu" @@ -104,7 +104,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v4 with: distribution: "zulu" @@ -136,7 +136,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v4 with: distribution: "zulu" @@ -174,7 +174,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v4 with: distribution: "zulu" @@ -226,7 +226,7 @@ jobs: property: version default: 0.0.1 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v4 with: distribution: "zulu" From ee1a04b870971748038b005e9f71e4881b65c913 Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 22 Feb 2025 17:22:40 -0300 Subject: [PATCH 137/186] Remove duplicate slash --- .../com/github/xpenatan/jparser/builder/DefaultBuildTarget.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java index 2e794e91..54f61829 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java @@ -238,6 +238,7 @@ public static ArrayList getCPPFiles(CustomFileDescriptor d Path of = Path.of(path); boolean remove = true; for(String cppInclude : cppIncludes) { + cppInclude = cppInclude.replace("//", "/"); PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("glob:" + cppInclude); boolean matches = pathMatcher.matches(of); if(matches) { From c9454ea6fd3f3e625f26eab77dcc0a0527466841 Mon Sep 17 00:00:00 2001 From: Natan Date: Sat, 22 Feb 2025 17:23:10 -0300 Subject: [PATCH 138/186] Remove duplicate slash --- .../com/github/xpenatan/jparser/builder/DefaultBuildTarget.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java index 54f61829..8adc1924 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/DefaultBuildTarget.java @@ -247,6 +247,7 @@ public static ArrayList getCPPFiles(CustomFileDescriptor d } } for(String cppExclude : cppExcludes) { + cppExclude = cppExclude.replace("//", "/"); PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("glob:" + cppExclude); boolean matches = pathMatcher.matches(of); if(matches) { From e752ba76d1c802fd0dc781c8a43bc09c5a7290c2 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 23 Feb 2025 19:45:32 -0300 Subject: [PATCH 139/186] Update android target to new solution and deprecated the old one using Android.mk and Application.m --- .github/workflows/build_and_upload.yml | 2 + .../lib/lib-build/src/main/java/BuildLib.java | 41 +++- .../builder/targets/AndroidTarget.java | 192 ++++++++++-------- .../builder/targets/AndroidTargetOld.java | 128 ++++++++++++ 4 files changed, 274 insertions(+), 89 deletions(-) create mode 100644 jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTargetOld.java diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index b9072c1c..3ba6d4ec 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -190,6 +190,8 @@ jobs: with: ndk-version: r25c add-to-path: false + env: + ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} - name: Change wrapper permissions run: chmod +x ./gradlew diff --git a/example/lib/lib-build/src/main/java/BuildLib.java b/example/lib/lib-build/src/main/java/BuildLib.java index 71c5f3db..8cc987c6 100644 --- a/example/lib/lib-build/src/main/java/BuildLib.java +++ b/example/lib/lib-build/src/main/java/BuildLib.java @@ -1,4 +1,5 @@ import com.github.xpenatan.jparser.builder.BuildMultiTarget; +import com.github.xpenatan.jparser.builder.targets.AndroidTargetOld; import com.github.xpenatan.jparser.builder.targets.AndroidTarget; import com.github.xpenatan.jparser.builder.targets.EmscriptenTarget; import com.github.xpenatan.jparser.builder.targets.IOSTarget; @@ -217,11 +218,11 @@ else if(buildType == 2) { return multiTarget; } - private static BuildMultiTarget getAndroidTarget(BuildToolOptions op) { + private static BuildMultiTarget getAndroidOldTarget(BuildToolOptions op) { BuildMultiTarget multiTarget = new BuildMultiTarget(); String sourceDir = op.getSourceDir(); - AndroidTarget androidTarget = new AndroidTarget(); + AndroidTargetOld androidTarget = new AndroidTargetOld(); androidTarget.addJNIHeaders(); androidTarget.headerDirs.add("-I" + sourceDir); @@ -233,6 +234,42 @@ private static BuildMultiTarget getAndroidTarget(BuildToolOptions op) { return multiTarget; } + private static BuildMultiTarget getAndroidTarget(BuildToolOptions op) { + BuildMultiTarget multiTarget = new BuildMultiTarget(); + String sourceDir = op.getSourceDir(); + String libBuildCPPPath = op.getModuleBuildCPPPath(); + + AndroidTarget.ApiLevel apiLevel = AndroidTarget.ApiLevel.Android_10_29; + ArrayList targets = new ArrayList<>(); + + targets.add(AndroidTarget.Target.x86); + targets.add(AndroidTarget.Target.x86_64); + targets.add(AndroidTarget.Target.armeabi_v7a); + targets.add(AndroidTarget.Target.arm64_v8a); + + for(int i = 0; i < targets.size(); i++) { + AndroidTarget.Target target = targets.get(i); + + // Make a static library + AndroidTarget compileStaticTarget = new AndroidTarget(target, apiLevel); + compileStaticTarget.isStatic = true; + compileStaticTarget.headerDirs.add("-I" + sourceDir); + compileStaticTarget.cppInclude.add(sourceDir + "**.cpp"); + multiTarget.add(compileStaticTarget); + + AndroidTarget linkTarget = new AndroidTarget(target, apiLevel); + linkTarget.addJNIHeaders(); + linkTarget.headerDirs.add("-I" + sourceDir); + linkTarget.headerDirs.add("-I" + op.getCustomSourceDir()); + linkTarget.headerDirs.add("-I" + libBuildCPPPath + "/src/jniglue"); + linkTarget.linkerFlags.add(libBuildCPPPath + "/libs/android/" + target.getFolder() +"/lib" + op.libName + ".a"); + linkTarget.cppInclude.add(libBuildCPPPath + "/src/jniglue/JNIGlue.cpp"); + multiTarget.add(linkTarget); + } + + return multiTarget; + } + private static BuildMultiTarget getIOSTarget(BuildToolOptions op) { BuildMultiTarget multiTarget = new BuildMultiTarget(); String sourceDir = op.getSourceDir(); diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java index e8939d6d..ed481c68 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTarget.java @@ -2,126 +2,144 @@ import com.github.xpenatan.jparser.builder.BuildConfig; import com.github.xpenatan.jparser.builder.DefaultBuildTarget; -import com.github.xpenatan.jparser.builder.JProcess; import com.github.xpenatan.jparser.core.util.CustomFileDescriptor; -import com.github.xpenatan.jparser.core.util.CustomFileDescriptor.FileType; import java.util.ArrayList; public class AndroidTarget extends DefaultBuildTarget { - public String androidABIS = "all"; - public String androidPlatform = "android-19"; + public static boolean DEBUG_BUILD; - public ArrayList customArgs = new ArrayList<>(); + private String ndkHome = System.getenv("ANDROID_NDK_HOME"); + private String target; + private String apiLevel; + private String sysroot; + private String archiver; - public AndroidTarget() { - this.libDirSuffix = "android/"; - this.tempBuildDir = "target/android"; + public AndroidTarget(Target target, ApiLevel apiLevel) { + cppCompiler.clear(); + linkerCompiler.clear(); + if(ndkHome == null) { + return; + } + this.libPrefix = "lib"; + + String osFolder = "windows-x86_64"; + if(isUnix()) { + osFolder = "linux-x86_64"; + } + else if(isMac()) { + // TODO Verify if this is correct + osFolder = "mac-x86_64"; + } + String toolchain = ndkHome + "/toolchains/llvm/prebuilt/" + osFolder; + String compiler = toolchain + "/bin/clang++"; // C++ compiler + archiver = toolchain + "/bin/llvm-ar"; // Archiver for static libraries + sysroot = toolchain + "/sysroot"; // System root for Android libraries + + // Target settings + this.target = target.value; + this.apiLevel = apiLevel.value; // Android API level (e.g., Android 10) + + String targetPath = target.folder; + + this.libDirSuffix = "android/" + targetPath; + this.tempBuildDir = "target/" + targetPath; + linkObjSuffix = ".o"; + + cppCompiler.add(compiler); + linkerCompiler.add(compiler); + cppCompiler.add("--target=" + this.target + this.apiLevel); + cppCompiler.add("--sysroot=" + sysroot); + cppCompiler.add("-fPIC"); cppFlags.add("-O2"); cppFlags.add("-Wall"); cppFlags.add("-D__ANDROID__"); cppFlags.add("-fvisibility=hidden"); cppFlags.add("-std=c++17"); - linkerFlags.add("-lm"); - cppInclude.add("**/jniglue/JNIGlue.cpp"); - headerDirs.add("jni-headers/linux"); + cppFlags.add("-c"); + libSuffix = "64.o"; } @Override - protected boolean build(BuildConfig config, CustomFileDescriptor buildTargetTemp) { - CustomFileDescriptor androidDir = config.buildDir; - if(!androidDir.exists()) { - androidDir.mkdirs(); - } - - CustomFileDescriptor applicationTemplate = new CustomFileDescriptor("android/Application.mk", FileType.Classpath); - String applicationStr = applicationTemplate.readString(); - applicationStr = applicationStr.replace("%androidABIs%", androidABIS); - applicationStr = applicationStr.replace("%androidPlat%", androidPlatform); - CustomFileDescriptor applicationFile = androidDir.child(applicationTemplate.name()); - applicationFile.writeString(applicationStr, false); - - CustomFileDescriptor androidTemplate = new CustomFileDescriptor("android/Android.mk", FileType.Classpath); - String androidStr = androidTemplate.readString(); - - String headerDirsStr = ""; - for(String headerDir : headerDirs) { - headerDir = headerDir.replace("-I", ""); - headerDirsStr += headerDir + " "; + protected void setup(BuildConfig config) { + if(ndkHome == null) { + return; } - headerDirsStr = headerDirsStr.trim(); - - String cppFlagsStr = ""; - for(String cppFlag : cppFlags) { - cppFlagsStr += cppFlag + " "; + if(isStatic) { + linkerCompiler.clear(); + linkerCompiler.add(archiver); + String staticLib = "libmystaticlib.a"; + linkerFlags.add("rcs"); + libSuffix = ".a"; } - cppFlagsStr = cppFlagsStr.trim(); - - String linkerFlagsStr = ""; - - for(String linkerFlag : linkerFlags) { - linkerFlagsStr += linkerFlag + " "; + else { + linkerFlags.add("-lm"); + linkerFlags.add("--target=" + target + apiLevel); + linkerFlags.add("--sysroot=" + sysroot); + linkerFlags.add("-shared"); + linkerFlags.add("-static-libstdc++"); // Statically link C++ runtime + libSuffix = ".so"; } - linkerFlagsStr = linkerFlagsStr.trim(); + } - ArrayList cppFiles = new ArrayList<>(getCPPFiles(config.buildSourceDir, cppInclude, cppExclude, filterCPPSuffix)); - for(CustomFileDescriptor sourceDir : config.additionalSourceDirs) { - ArrayList cppFiles1 = getCPPFiles(sourceDir, cppInclude, cppExclude, filterCPPSuffix); - cppFiles.addAll(cppFiles1); + @Override + protected void onLink(ArrayList compiledObject, String objFilePath, String libPath) { + if(isStatic) { + linkerCommands.addAll(linkerCompiler); + linkerCommands.addAll(linkerFlags); + linkerCommands.add(libPath); + linkerCommands.add("@" + objFilePath); } - - String srcFilesStr = ""; - for(CustomFileDescriptor file : cppFiles) { - String path = file.path(); - String sourceBasePath = config.buildDir.path(); - String pathWithoutBase = path.replace(sourceBasePath, ""); - pathWithoutBase = pathWithoutBase.replaceFirst("/", ""); - srcFilesStr += "FILE_LIST += $(wildcard $(LOCAL_PATH)/" + pathWithoutBase + ")\n"; + else { + super.onLink(compiledObject, objFilePath, libPath); } + } - srcFilesStr = srcFilesStr.trim(); - - androidStr = androidStr.replace("%libName%", config.libName); - androidStr = androidStr.replace("%headerDirs%", headerDirsStr); - androidStr = androidStr.replace("%cppFlags%", cppFlagsStr); - androidStr = androidStr.replace("%linkerFlags%", linkerFlagsStr); - androidStr = androidStr.replace("%srcFiles%", srcFilesStr); + public void addJNIHeaders() { + headerDirs.add("-Ijni-headers/"); + headerDirs.add("-Ijni-headers/linux"); + headerDirs.add("-Ijni-headers/win32"); + headerDirs.add("-Ijni-headers/mac"); + } - CustomFileDescriptor androidFile = androidDir.child(androidTemplate.name()); - androidFile.writeString(androidStr, false); + public enum Target { + arm64_v8a("aarch64-linux-android", "arm64-v8a"), + armeabi_v7a("armv7a-linux-androideabi", "armeabi-v7a"), + x86_64("x86_64-linux-android", "x86_64"), + x86("i686-linux-android", "x86"); - String ndkHome = System.getenv("NDK_HOME"); + private String value; + private String folder; - if(ndkHome != null) { - ndkHome += "/"; - } - else { - ndkHome = ""; + Target(String value, String folder) { + this.value = value; + this.folder = folder; } - String androidCommand = ndkHome + "ndk-build"; - if(isWindows()) { - androidCommand += ".cmd"; + public String getFolder() { + return folder; } - if(multiCoreCompile) { - int i = Runtime.getRuntime().availableProcessors(); - customArgs.add("-j" + i ); - } + } - CustomFileDescriptor libTarget = config.libDir.child("android"); - ArrayList commands = new ArrayList<>(); - commands.add(androidCommand); - commands.addAll(customArgs); - commands.add("NDK_PROJECT_PATH=."); - commands.add("NDK_APPLICATION_MK=Application.mk"); - commands.add(" NDK_LIBS_OUT=" + libTarget.path()); - if(!JProcess.startProcess(androidDir.file(), commands)) { - return false; + public enum ApiLevel { + Android_16_36("36"), + Android_15_35("35"), + Android_14_34("34"), + Android_13_33("33"), + Android_12_32("32"), + Android_12_31("31"), + Android_11_30("30"), + Android_10_29("29"), + Android_09_28("28"); + + private String value; + + ApiLevel(String value) { + this.value = value; } - return true; } } diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTargetOld.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTargetOld.java new file mode 100644 index 00000000..96cee793 --- /dev/null +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/AndroidTargetOld.java @@ -0,0 +1,128 @@ +package com.github.xpenatan.jparser.builder.targets; + +import com.github.xpenatan.jparser.builder.BuildConfig; +import com.github.xpenatan.jparser.builder.DefaultBuildTarget; +import com.github.xpenatan.jparser.builder.JProcess; +import com.github.xpenatan.jparser.core.util.CustomFileDescriptor; +import com.github.xpenatan.jparser.core.util.CustomFileDescriptor.FileType; +import java.util.ArrayList; + +@Deprecated +public class AndroidTargetOld extends DefaultBuildTarget { + + public String androidABIS = "all"; + public String androidPlatform = "android-19"; + + public ArrayList customArgs = new ArrayList<>(); + + public AndroidTargetOld() { + this.libDirSuffix = "android/"; + this.tempBuildDir = "target/android"; + + cppFlags.add("-O2"); + cppFlags.add("-Wall"); + cppFlags.add("-D__ANDROID__"); + cppFlags.add("-fvisibility=hidden"); + cppFlags.add("-std=c++17"); + linkerFlags.add("-lm"); + + cppInclude.add("**/jniglue/JNIGlue.cpp"); + headerDirs.add("jni-headers/linux"); + } + + @Override + protected boolean build(BuildConfig config, CustomFileDescriptor buildTargetTemp) { + CustomFileDescriptor androidDir = config.buildDir; + if(!androidDir.exists()) { + androidDir.mkdirs(); + } + + CustomFileDescriptor applicationTemplate = new CustomFileDescriptor("android/Application.mk", FileType.Classpath); + String applicationStr = applicationTemplate.readString(); + applicationStr = applicationStr.replace("%androidABIs%", androidABIS); + applicationStr = applicationStr.replace("%androidPlat%", androidPlatform); + CustomFileDescriptor applicationFile = androidDir.child(applicationTemplate.name()); + applicationFile.writeString(applicationStr, false); + + CustomFileDescriptor androidTemplate = new CustomFileDescriptor("android/Android.mk", FileType.Classpath); + String androidStr = androidTemplate.readString(); + + String headerDirsStr = ""; + for(String headerDir : headerDirs) { + headerDir = headerDir.replace("-I", ""); + headerDirsStr += headerDir + " "; + } + headerDirsStr = headerDirsStr.trim(); + + String cppFlagsStr = ""; + + for(String cppFlag : cppFlags) { + cppFlagsStr += cppFlag + " "; + } + cppFlagsStr = cppFlagsStr.trim(); + + String linkerFlagsStr = ""; + + for(String linkerFlag : linkerFlags) { + linkerFlagsStr += linkerFlag + " "; + } + linkerFlagsStr = linkerFlagsStr.trim(); + + ArrayList cppFiles = new ArrayList<>(getCPPFiles(config.buildSourceDir, cppInclude, cppExclude, filterCPPSuffix)); + for(CustomFileDescriptor sourceDir : config.additionalSourceDirs) { + ArrayList cppFiles1 = getCPPFiles(sourceDir, cppInclude, cppExclude, filterCPPSuffix); + cppFiles.addAll(cppFiles1); + } + + String srcFilesStr = ""; + for(CustomFileDescriptor file : cppFiles) { + String path = file.path(); + String sourceBasePath = config.buildDir.path(); + String pathWithoutBase = path.replace(sourceBasePath, ""); + pathWithoutBase = pathWithoutBase.replaceFirst("/", ""); + srcFilesStr += "FILE_LIST += $(wildcard $(LOCAL_PATH)/" + pathWithoutBase + ")\n"; + } + + srcFilesStr = srcFilesStr.trim(); + + androidStr = androidStr.replace("%libName%", config.libName); + androidStr = androidStr.replace("%headerDirs%", headerDirsStr); + androidStr = androidStr.replace("%cppFlags%", cppFlagsStr); + androidStr = androidStr.replace("%linkerFlags%", linkerFlagsStr); + androidStr = androidStr.replace("%srcFiles%", srcFilesStr); + + CustomFileDescriptor androidFile = androidDir.child(androidTemplate.name()); + androidFile.writeString(androidStr, false); + + String ndkHome = System.getenv("NDK_HOME"); + + if(ndkHome != null) { + ndkHome += "/"; + } + else { + ndkHome = ""; + } + + String androidCommand = ndkHome + "ndk-build"; + if(isWindows()) { + androidCommand += ".cmd"; + } + + if(multiCoreCompile) { + int i = Runtime.getRuntime().availableProcessors(); + customArgs.add("-j" + i ); + } + + CustomFileDescriptor libTarget = config.libDir.child("android"); + ArrayList commands = new ArrayList<>(); + commands.add(androidCommand); + commands.addAll(customArgs); + commands.add("NDK_PROJECT_PATH=."); + commands.add("NDK_APPLICATION_MK=Application.mk"); + commands.add(" NDK_LIBS_OUT=" + libTarget.path()); + if(!JProcess.startProcess(androidDir.file(), commands)) { + return false; + } + return true; + } +} From 467bbc42b3b23a2c5f0ee6008cb4d858c187542a Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 27 Feb 2025 10:05:51 -0300 Subject: [PATCH 140/186] Add Arithmetic / Compound Assignment Operators. Fix wasm big int issue --- .github/workflows/build_and_upload.yml | 2 + .../xpenatan/jparser/example/app/TestLib.java | 93 ++++++++++++++++++- .../lib/lib-build/src/main/cpp/TestLib.idl | 15 +++ .../src/main/cpp/source/TestLib/src/TestLib.h | 64 +++++++++++++ .../builder/targets/EmscriptenTarget.java | 4 + .../xpenatan/jparser/cpp/CppCodeParser.java | 44 +++++---- .../github/xpenatan/jparser/idl/IDLClass.java | 8 -- .../jparser/idl/parser/IDLMethodParser.java | 2 +- 8 files changed, 203 insertions(+), 29 deletions(-) diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index 3ba6d4ec..941feea4 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -148,6 +148,8 @@ jobs: - name: Install emscripten uses: mymindstorm/setup-emsdk@v14 + with: + version: 4.0.4 - name: Change wrapper permissions run: chmod +x ./gradlew diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java index 99a9b304..3006cc7b 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java @@ -1,5 +1,7 @@ package com.github.xpenatan.jparser.example.app; +import com.badlogic.gdx.Application; +import com.badlogic.gdx.Gdx; import com.github.xpenatan.jparser.example.testlib.CallbackClass; import com.github.xpenatan.jparser.example.testlib.CallbackClassManual; import com.github.xpenatan.jparser.example.testlib.DefaultCallbackClass; @@ -9,6 +11,7 @@ import com.github.xpenatan.jparser.example.testlib.TestNamespaceClass; import com.github.xpenatan.jparser.example.testlib.TestObjectClass; import com.github.xpenatan.jparser.example.testlib.TestObjectClassArray; +import com.github.xpenatan.jparser.example.testlib.TestOperatorClass; import com.github.xpenatan.jparser.example.testlib.idl.helper.IDLString; public class TestLib { @@ -24,6 +27,7 @@ public static boolean test() { boolean callbackTest = testCallbackClass(); boolean callbackTestManual = testCallbackClassManual(); boolean namespaceTest = testNamespaceClass(); + boolean operatorTest = testOperatorClass(); System.out.println("constructorTest: " + constructorTest); System.out.println("stringConstructorTest: " + stringConstructorTest); @@ -34,8 +38,11 @@ public static boolean test() { System.out.println("staticMethodTest: " + staticMethodTest); System.out.println("callbackTest: " + callbackTest); System.out.println("namespaceTest: " + namespaceTest); + System.out.println("operatorTest: " + operatorTest); + return constructorTest && stringConstructorTest && attributeTest && staticAttributeTest - && attributeArrayTest && methodTest && staticMethodTest && callbackTest && callbackTestManual && namespaceTest; + && attributeArrayTest && methodTest && staticMethodTest && callbackTest + && callbackTestManual && namespaceTest && operatorTest; } private static boolean testConstructorClass() { @@ -276,6 +283,11 @@ private static boolean testStaticMethodClass() { private static boolean testCallbackClass() { { + if(Gdx.app.getType() == Application.ApplicationType.WebGL) { + // TODO Not supported yet + return true; + } + TestCallbackClass test = new TestCallbackClass(); try { boolean[] internal_onVoidCallback = { false }; @@ -596,4 +608,83 @@ private static boolean testNamespaceClass() { } return true; } + + private static boolean testOperatorClass() { + try { + TestOperatorClass operatorClass = new TestOperatorClass(); + TestOperatorClass otherOPClass = new TestOperatorClass(); + otherOPClass.setValue(3); + + // Arithmetic Operators + { + operatorClass.setValue(10); + TestOperatorClass obj = operatorClass.addValue(otherOPClass); + float value = obj.getValue(); + if(!(value == 13 && (obj != operatorClass && obj != otherOPClass))) { + throw new RuntimeException("testOperatorClass '+' !(value == 13)"); + } + } + { + operatorClass.setValue(10); + TestOperatorClass obj = operatorClass.subValue(otherOPClass); + float value = obj.getValue(); + if(!(value == 7 && (obj != operatorClass && obj != otherOPClass))) { + throw new RuntimeException("testOperatorClass '-' !(value == 7)"); + } + } + { + operatorClass.setValue(10); + TestOperatorClass obj = operatorClass.mulValue(otherOPClass); + float value = obj.getValue(); + if(!(value == 30 && (obj != operatorClass && obj != otherOPClass))) { + throw new RuntimeException("testOperatorClass '*' !(value == 30)"); + } + } + { + operatorClass.setValue(30); + TestOperatorClass obj = operatorClass.divValue(otherOPClass); + float value = obj.getValue(); + if(!(value == 10 && (obj != operatorClass && obj != otherOPClass))) { + throw new RuntimeException("testOperatorClass '/' !(value == 10)"); + } + } + // Compound Assignment Operators + { + operatorClass.setValue(10); + TestOperatorClass obj = operatorClass.addRef(otherOPClass); + float value = obj.getValue(); + if(!(value == 13 && (obj == operatorClass))) { + throw new RuntimeException("testOperatorClass '+' !(value == 13)"); + } + } + { + operatorClass.setValue(10); + TestOperatorClass obj = operatorClass.subRef(otherOPClass); + float value = obj.getValue(); + if(!(value == 7 && (obj == operatorClass))) { + throw new RuntimeException("testOperatorClass '-' !(value == 7)"); + } + } + { + operatorClass.setValue(10); + TestOperatorClass obj = operatorClass.mulRef(otherOPClass); + float value = obj.getValue(); + if(!(value == 30 && (obj == operatorClass))) { + throw new RuntimeException("testOperatorClass '*' !(value == 30)"); + } + } + { + operatorClass.setValue(30); + TestOperatorClass obj = operatorClass.divRef(otherOPClass); + float value = obj.getValue(); + if(!(value == 10 && (obj == operatorClass))) { + throw new RuntimeException("testOperatorClass '/' !(value == 10)"); + } + } + return true; + } catch(Throwable e) { + e.printStackTrace(); + } + return false; + } } \ No newline at end of file diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index 6178e30a..e7d57617 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -217,6 +217,21 @@ interface TestNamespaceClass { long getMethod01Value(); }; +interface TestOperatorClass { + void TestOperatorClass(); + void TestOperatorClass(float value); + [Operator="+", Value] TestOperatorClass addValue([Const, Ref] TestOperatorClass other); + [Operator="-", Value] TestOperatorClass subValue([Const, Ref] TestOperatorClass other); + [Operator="*", Value] TestOperatorClass mulValue([Const, Ref] TestOperatorClass other); + [Operator="/", Value] TestOperatorClass divValue([Const, Ref] TestOperatorClass other); + [Operator="+=", Ref] TestOperatorClass addRef([Const, Ref] TestOperatorClass other); + [Operator="-=", Ref] TestOperatorClass subRef([Const, Ref] TestOperatorClass other); + [Operator="*=", Ref] TestOperatorClass mulRef([Const, Ref] TestOperatorClass other); + [Operator="/=", Ref] TestOperatorClass divRef([Const, Ref] TestOperatorClass other); + float getValue(); + void setValue(float val); +}; + enum TestEnumWithinClass { "TestEnumClass::e_val" }; diff --git a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h index 1dbc9706..137de348 100644 --- a/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h +++ b/example/lib/lib-build/src/main/cpp/source/TestLib/src/TestLib.h @@ -201,6 +201,70 @@ class TestMethodClass { long long getLongLongValue01() { return longLongValue01; }; }; +class TestOperatorClass { +private: + float value; + +public: + // Constructor + TestOperatorClass() { value = 0; } + TestOperatorClass(float value) { this->value = value; } + + // Arithmetic Operators + TestOperatorClass operator+(const TestOperatorClass& other) const { return TestOperatorClass(value + other.value); } + TestOperatorClass operator-(const TestOperatorClass& other) const { return TestOperatorClass(value - other.value); } + TestOperatorClass operator*(const TestOperatorClass& other) const { return TestOperatorClass(value * other.value); } + TestOperatorClass operator/(const TestOperatorClass& other) const { + if (other.value != 0) return TestOperatorClass(value / other.value); + cout << "Error: Division by zero!" << endl; + return *this; + } + TestOperatorClass operator-() const { return TestOperatorClass(-value); } // Unary minus + + // Compound Assignment Operators + TestOperatorClass& operator+=(const TestOperatorClass& other) { value += other.value; return *this; } + TestOperatorClass& operator-=(const TestOperatorClass& other) { value -= other.value; return *this; } + TestOperatorClass& operator*=(const TestOperatorClass& other) { value *= other.value; return *this; } + TestOperatorClass& operator/=(const TestOperatorClass& other) { + if (other.value != 0) value /= other.value; + else cout << "Error: Division by zero!" << endl; + return *this; + } + + // Comparison Operators + bool operator==(const TestOperatorClass& other) const { return value == other.value; } + bool operator!=(const TestOperatorClass& other) const { return value != other.value; } + bool operator<(const TestOperatorClass& other) const { return value < other.value; } + bool operator>(const TestOperatorClass& other) const { return value > other.value; } + bool operator<=(const TestOperatorClass& other) const { return value <= other.value; } + bool operator>=(const TestOperatorClass& other) const { return value >= other.value; } + + // Increment and Decrement Operators + TestOperatorClass& operator++() { value += 1.0; return *this; } // Prefix increment + TestOperatorClass operator++(int) { TestOperatorClass temp = *this; value += 1.0; return temp; } // Postfix increment + TestOperatorClass& operator--() { value -= 1.0; return *this; } // Prefix decrement + TestOperatorClass operator--(int) { TestOperatorClass temp = *this; value -= 1.0; return temp; } // Postfix decrement + + // Bitwise Operators (optional, but included for completeness with float caveats) + TestOperatorClass operator&(const TestOperatorClass& other) const { return TestOperatorClass(static_cast(static_cast(value) & static_cast(other.value))); } + TestOperatorClass operator|(const TestOperatorClass& other) const { return TestOperatorClass(static_cast(static_cast(value) | static_cast(other.value))); } + TestOperatorClass operator^(const TestOperatorClass& other) const { return TestOperatorClass(static_cast(static_cast(value) ^ static_cast(other.value))); } + TestOperatorClass operator~() const { return TestOperatorClass(static_cast(~static_cast(value))); } + TestOperatorClass operator<<(const TestOperatorClass& other) const { return TestOperatorClass(static_cast(static_cast(value) << static_cast(other.value))); } + TestOperatorClass operator>>(const TestOperatorClass& other) const { return TestOperatorClass(static_cast(static_cast(value) >> static_cast(other.value))); } + + // Compound Bitwise Assignment Operators + TestOperatorClass& operator&=(const TestOperatorClass& other) { value = static_cast(static_cast(value) & static_cast(other.value)); return *this; } + TestOperatorClass& operator|=(const TestOperatorClass& other) { value = static_cast(static_cast(value) | static_cast(other.value)); return *this; } + TestOperatorClass& operator^=(const TestOperatorClass& other) { value = static_cast(static_cast(value) ^ static_cast(other.value)); return *this; } + TestOperatorClass& operator<<=(const TestOperatorClass& other) { value = static_cast(static_cast(value) << static_cast(other.value)); return *this; } + TestOperatorClass& operator>>=(const TestOperatorClass& other) { value = static_cast(static_cast(value) >> static_cast(other.value)); return *this; } + + // Accessor + float getValue() const { return value; } + void setValue(float val) { this->value = val; } +}; + class TestStaticMethodClass { private: inline static int intValue01; diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java index 8b579645..b677145b 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java @@ -124,6 +124,10 @@ protected boolean build(BuildConfig config, CustomFileDescriptor buildTargetTemp if(IS_WASM) { linkerFlags.add("-s"); linkerFlags.add("WASM=1"); + linkerFlags.add("-s"); + + // Disable big int because of conversion bug + linkerFlags.add("WASM_BIGINT=0"); } else { linkerFlags.add("-s"); diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index 1381fd7a..aa061f50 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -147,6 +147,13 @@ public class CppCodeParser extends IDLDefaultCodeParser { "[COPY_PARAM] = nativeObject->[METHOD];\n" + "return (jlong)&[COPY_PARAM];"; + protected static final String METHOD_GET_OBJ_VALUE_ARITHMETIC_OPERATOR_TEMPLATE = + "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + + "static [COPY_TYPE] [COPY_PARAM];\n" + + "[COPY_PARAM] = [OPERATOR];\n" + + "return (jlong)&[COPY_PARAM];"; + + protected static final String METHOD_GET_OBJ_VALUE_STATIC_TEMPLATE = "\nstatic [COPY_TYPE] [COPY_PARAM];\n" + "[COPY_PARAM] = [TYPE]::[METHOD];\n" + @@ -657,7 +664,7 @@ private void setupMethodGenerated(IDLMethod idlMethod, String param, ClassOrInte constTag = "const "; } - String operator = getOperation(idlMethod.operator, param); + String operator = getOperator(idlMethod.operator, param); String content = null; IDLMethodOperation.Op op = IDLMethodOperation.getEnum(idlMethod, methodDeclaration, nativeMethod); switch(op) { @@ -699,11 +706,20 @@ private void setupMethodGenerated(IDLMethod idlMethod, String param, ClassOrInte returnTypeName = retTypeClass.classHeader.prefixName + returnTypeName; } String copyParam = "copy_addr"; - content = METHOD_GET_OBJ_VALUE_TEMPLATE - .replace(TEMPLATE_TAG_METHOD, methodCaller) - .replace(TEMPLATE_TAG_TYPE, classTypeName) - .replace(TEMPLATE_TAG_COPY_TYPE, returnTypeName) - .replace(TEMPLATE_TAG_COPY_PARAM, copyParam); + if(operator.isEmpty()) { + content = METHOD_GET_OBJ_VALUE_TEMPLATE + .replace(TEMPLATE_TAG_METHOD, methodCaller) + .replace(TEMPLATE_TAG_TYPE, classTypeName) + .replace(TEMPLATE_TAG_COPY_TYPE, returnTypeName) + .replace(TEMPLATE_TAG_COPY_PARAM, copyParam); + } + else { + content = METHOD_GET_OBJ_VALUE_ARITHMETIC_OPERATOR_TEMPLATE + .replace(TEMPLATE_TAG_OPERATOR, operator) + .replace(TEMPLATE_TAG_TYPE, classTypeName) + .replace(TEMPLATE_TAG_COPY_TYPE, returnTypeName) + .replace(TEMPLATE_TAG_COPY_PARAM, copyParam); + } } break; case GET_OBJ_POINTER_STATIC: @@ -725,25 +741,15 @@ private void setupMethodGenerated(IDLMethod idlMethod, String param, ClassOrInte nativeMethod.setBlockComment(blockComment); } - private static String getOperation(String operatorCode, String param) { + private static String getOperator(String operatorCode, String param) { String oper = ""; if(!operatorCode.isEmpty()) { if(operatorCode.equals("[]")) { oper = "nativeObject[" + param + "]"; } - else if(operatorCode.equals("=")){ - oper = "(*nativeObject = " + param + ")"; + else { + oper = "(*nativeObject " + operatorCode + " " + param + ")"; } - //TODO add more operator c++ code -// else if(operatorCode.equals("+=")){ -// oper = " += " + param; -// } -// else if(operatorCode.equals("-=")){ -// oper = " -= " + param; -// } -// else if(operatorCode.equals("*=")){ -// oper = " *= " + param; -// } } return oper; } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java index 72b5c502..5c241cca 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java @@ -147,12 +147,4 @@ public IDLMethod getMethod(String methodName) { return null; } - public IDLMethod getOperatorMethod(String operator) { - for(IDLMethod method : methods) { - if(method.operator.equals(operator)) { - return method; - } - } - return null; - } } \ No newline at end of file diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java index 59388524..eba11774 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java @@ -256,7 +256,7 @@ private static BlockStmt generateTempObjects(boolean isReturnValue, ClassOrInter boolean isRetSameAsClass = false; - if(!operator.isEmpty() && className.equals(returnTypeName)) { + if(!operator.isEmpty() && className.equals(returnTypeName) && !isReturnValue) { // is pointer or ref // if its operator and return type is same as class name don't create temp object isRetSameAsClass = true; } From 0a688cbaed5dba73e99c9d1d0fe572c751bfa008 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 27 Feb 2025 10:16:02 -0300 Subject: [PATCH 141/186] Change typedef to using --- example/lib/lib-build/src/main/cpp/TestLib.idl | 2 +- example/lib/lib-build/src/main/cpp/custom/CustomCode.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/example/lib/lib-build/src/main/cpp/TestLib.idl b/example/lib/lib-build/src/main/cpp/TestLib.idl index e7d57617..abc832b3 100644 --- a/example/lib/lib-build/src/main/cpp/TestLib.idl +++ b/example/lib/lib-build/src/main/cpp/TestLib.idl @@ -8,7 +8,7 @@ // It needs to be at the same order if both have the same parameter size. // TestConstructorClass works because it have different parameter size. From the [BUG] above, don't use string or it will fail at runtime. // * Arrays parameters for example "void method(int[] array)" is converted to IDLIntArray class object behind the scene because interacting with array is better using native code. -// For custom types is better to use typedef. See TestObjectClassArray in CustomCode.h +// For custom types is better to use 'using' alias. See TestObjectClassArray in CustomCode.h // * Array get_ shape the same object for every index. Don't keep object reference. // * Emscripten WebIDL callbacks don't work with overloaded methods so its better to use _[N] at the end of the method // * Emscripten class methods don't work with overloaded methods with different parameter order so its better to use _[N] at the end of the method diff --git a/example/lib/lib-build/src/main/cpp/custom/CustomCode.h b/example/lib/lib-build/src/main/cpp/custom/CustomCode.h index 3957cace..c2ed825f 100644 --- a/example/lib/lib-build/src/main/cpp/custom/CustomCode.h +++ b/example/lib/lib-build/src/main/cpp/custom/CustomCode.h @@ -1,8 +1,8 @@ #include "IDLHelper.h" #include "TestLib.h" -typedef TestEnumClass::TestEnumWithinClass TestEnumWithinClass; -typedef TestEnumClass::TestEnumClassWithinClass TestEnumClassWithinClass; -typedef TestEnumNamespace::TestEnumInNamespace TestEnumInNamespace; +using TestEnumWithinClass = TestEnumClass::TestEnumWithinClass; +using TestEnumClassWithinClass = TestEnumClass::TestEnumClassWithinClass; +using TestEnumInNamespace = TestEnumNamespace::TestEnumInNamespace; -typedef IDLArray TestObjectClassArray; \ No newline at end of file +using TestObjectClassArray = IDLArray; \ No newline at end of file From 06b64597dc585e2fe5aa6b73b3b67c6d417f7b8a Mon Sep 17 00:00:00 2001 From: Natan Date: Fri, 28 Feb 2025 08:23:29 -0300 Subject: [PATCH 142/186] Fix generating native methods for multiple constructors --- .../idl/parser/IDLConstructorParser.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java index 125f34dd..65e9ce05 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java @@ -97,9 +97,23 @@ public static ConstructorDeclaration getOrCreateConstructorDeclaration(IDLDefaul public static MethodDeclaration setupConstructor(IDLConstructor idlConstructor, ClassOrInterfaceDeclaration classDeclaration, ConstructorDeclaration constructorDeclaration) { NodeList parameters = constructorDeclaration.getParameters(); Type type = StaticJavaParser.parseType(classDeclaration.getNameAsString()); - boolean isStatic = true; - MethodDeclaration nativeMethod = IDLMethodParser.generateNativeMethod("create", parameters, type, isStatic); + + String additionalName = ""; + + // Constructor needs to have type in the name because there are some cases that multiple + // parameters with different type will skip creating this native method if they are equal. + // Since the parameters object is converter to long. It's impossible to override multiple methods + // with the same pointers type. + // TODO maybe add parameter type in all native method names. + for(int i = 0; i < parameters.size(); i++) { + Parameter parameter = parameters.get(i); + String typeName = parameter.getType().toString(); + additionalName += "_" + typeName; + } + + String methodName = "create" + additionalName; + MethodDeclaration nativeMethod = IDLMethodParser.generateNativeMethod(methodName, parameters, type, isStatic); if(!JParserHelper.containsMethod(classDeclaration, nativeMethod)) { //Add native method if it does not exist From 09987a2f47e593f03057878786725ababec30a8a Mon Sep 17 00:00:00 2001 From: Natan Date: Fri, 28 Feb 2025 08:23:45 -0300 Subject: [PATCH 143/186] reduce android gradle version --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 52ef4af3..357a2e61 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ buildscript { val kotlinVersion = "2.1.10" dependencies { - classpath("com.android.tools.build:gradle:8.2.0") + classpath("com.android.tools.build:gradle:8.0.2") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") } } From 01c521dfd73f23f50f5cee34453c6897b2d7fae7 Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 3 Mar 2025 07:53:01 -0300 Subject: [PATCH 144/186] update gradle plugin --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 357a2e61..07b54e2f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ buildscript { val kotlinVersion = "2.1.10" dependencies { - classpath("com.android.tools.build:gradle:8.0.2") + classpath("com.android.tools.build:gradle:7.3.1") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") } } From 0aab85aa652d2d69158b67dce0b73075d1053aba Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 3 Mar 2025 07:53:15 -0300 Subject: [PATCH 145/186] Fix adding namespace to cpp types --- .../xpenatan/jparser/idl/IDLAttribute.java | 8 +- .../xpenatan/jparser/idl/IDLMethod.java | 1 + .../xpenatan/jparser/idl/IDLParameter.java | 8 +- .../xpenatan/jparser/idl/IDLReader.java | 97 ++++++++++++++----- 4 files changed, 89 insertions(+), 25 deletions(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java index 29e6c072..74171d4b 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java @@ -15,6 +15,7 @@ public class IDLAttribute { public boolean isConst = false; public boolean isValue = false; public boolean isArray = false; + public IDLClassOrEnum idlClassOrEnum; public IDLAttribute(IDLFile idlFile) { this.idlFile = idlFile; @@ -66,7 +67,12 @@ public void initAttribute(String line) { public String getCPPType() { //Attributes don't set/get arrays so we remove it - return IDLHelper.getCPPReturnType(idlType).replace("[]", ""); + String fullType = idlType; + if(idlClassOrEnum != null && idlClassOrEnum.isClass()) { + IDLClass aClass = idlClassOrEnum.asClass(); + fullType = aClass.getName(); + } + return IDLHelper.getCPPReturnType(fullType).replace("[]", ""); } public String getJavaType() { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java index 42752b5b..89b6b6b0 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java @@ -12,6 +12,7 @@ public class IDLMethod { public String line; public String paramsLine; public String returnType; + public IDLClassOrEnum returnClassType; public String name; public boolean isReturnArray; public boolean skip = false; diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java index 63098b1d..e04c5eaf 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java @@ -9,6 +9,7 @@ public class IDLParameter { public final IDLFile idlFile; public IDLMethod idlMethod; public IDLConstructor idlConstructor; + public IDLClassOrEnum idlClassOrEnum; public String line; public String idlType; @@ -78,7 +79,12 @@ public void initParameter(String line) { } public String getCPPType() { - return IDLHelper.getCPPReturnType(idlType); + String fullType = idlType; + if(idlClassOrEnum != null && idlClassOrEnum.isClass()) { + IDLClass aClass = idlClassOrEnum.asClass(); + fullType = aClass.getName(); + } + return IDLHelper.getCPPReturnType(fullType); } public String getJavaType() { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java index 994be339..cd6b6e99 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java @@ -61,37 +61,58 @@ public IDLEnum getEnum(String name) { return null; } - public static IDLReader readIDL(String idlDir) { - IDLReader reader = new IDLReader(); - try { - idlDir = new File(idlDir).getCanonicalPath() + File.separator; - } catch(IOException e) { - throw new RuntimeException("IDL file not found: " + idlDir); + public IDLClassOrEnum getClassOrEnum(String name) { + for(int i = 0; i < fileArray.size(); i++) { + IDLFile idlFile = fileArray.get(i); + IDLClass idlClass = idlFile.getClass(name); + if(idlClass != null) { + return idlClass; + } + IDLEnum idlEnum = idlFile.getEnum(name); + if(idlEnum != null) { + return idlEnum; + } } - IDLFile idlFile = parseFile(idlDir); - reader.fileArray.add(idlFile); - return reader; + return null; } - public static void addIDL(IDLReader reader, String idlDir) { - try { - idlDir = new File(idlDir).getCanonicalPath() + File.separator; - } catch(IOException e) { - throw new RuntimeException("IDL file not found: " + idlDir); + public ArrayList getAllClasses() { + ArrayList classes = new ArrayList<>(); + for(int i = 0; i < fileArray.size(); i++) { + IDLFile idlFile = fileArray.get(i); + classes.addAll(idlFile.classArray); } - IDLFile idlFile = parseFile(idlDir); - reader.fileArray.add(idlFile); + return classes; } - public static IDLReader readIDL(ArrayList idlDirs) { + public static IDLReader readIDL(String ...idlDirs) { IDLReader reader = new IDLReader(); - for(String idlDir : idlDirs) { - IDLFile idlFile = parseFile(idlDir); - reader.fileArray.add(idlFile); + + for(int i = 0; i < idlDirs.length; i++) { + String idlDir = idlDirs[i]; + try { + idlDir = new File(idlDir).getCanonicalPath() + File.separator; + IDLFile idlFile = parseFile(idlDir); + reader.fileArray.add(idlFile); + } catch(IOException e) { + throw new RuntimeException("IDL file not found: " + idlDir); + } } + + setupClasses(reader); return reader; } +// public static void addIDL(IDLReader reader, String idlDir) { +// try { +// idlDir = new File(idlDir).getCanonicalPath() + File.separator; +// } catch(IOException e) { +// throw new RuntimeException("IDL file not found: " + idlDir); +// } +// IDLFile idlFile = parseFile(idlDir); +// reader.fileArray.add(idlFile); +// } + public static IDLFile parseFile(String path) { path = path.replace("\\", File.separator); File file = new File(path); //creates a new file instance @@ -124,7 +145,6 @@ public static IDLFile parseFile(InputStreamReader inputStreamReader, String idlN ArrayList classList = new ArrayList<>(); parseFile(idlFile, classList); idlFile.classArray.addAll(classList); - configCallbacks(idlFile, classList); } catch(Throwable t) { t.printStackTrace(); @@ -206,7 +226,38 @@ private static void parseFile(IDLFile idlFile, ArrayList classLi } } - private static void configCallbacks(IDLFile idlFile, ArrayList classList) { + private static void setupClasses(IDLReader idlReader) { + ArrayList classList = idlReader.getAllClasses(); + configClassType(idlReader, classList); + configCallbacks(idlReader, classList); + } + + private static void configClassType(IDLReader idlReader, ArrayList classList) { + // Setup all attributes and parameters type + for(int i = 0; i < classList.size(); i++) { + IDLClassOrEnum idlClassOrEnum = classList.get(i); + if(idlClassOrEnum.isClass()) { + IDLClass idlClass = idlClassOrEnum.asClass(); + for(IDLAttribute attribute : idlClass.attributes) { + String idlType = attribute.idlType; + IDLClassOrEnum childClassOrEnum = idlReader.getClassOrEnum(idlType); + attribute.idlClassOrEnum = childClassOrEnum; + } + for(IDLMethod method : idlClass.methods) { + for(IDLParameter parameter : method.parameters) { + String idlType = parameter.idlType; + IDLClassOrEnum childClassOrEnum = idlReader.getClassOrEnum(idlType); + parameter.idlClassOrEnum = childClassOrEnum; + } + String returnType = method.returnType; + IDLClassOrEnum childClassOrEnum = idlReader.getClassOrEnum(returnType); + method.returnClassType = childClassOrEnum; + } + } + } + } + + private static void configCallbacks(IDLReader idlReader, ArrayList classList) { for(int i = 0; i < classList.size(); i++) { IDLClassOrEnum idlClassOrEnum = classList.get(i); if(idlClassOrEnum.isClass()) { @@ -215,7 +266,7 @@ private static void configCallbacks(IDLFile idlFile, ArrayList c if(jsImplementation != null) { jsImplementation = jsImplementation.trim(); if(!jsImplementation.isEmpty()) { - IDLClass callbackClass = idlFile.getClass(jsImplementation); + IDLClass callbackClass = idlReader.getClass(jsImplementation); if(callbackClass != null) { if(callbackClass.callbackImpl == null) { callbackClass.callbackImpl = idlCallbackImpl; From e1ee1e8d6f16dc3f827b7e0d7409f1b2061b1abb Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 3 Mar 2025 21:11:36 -0300 Subject: [PATCH 146/186] Fix cpp parser getting class name with namespace --- .../xpenatan/jparser/cpp/CppCodeParser.java | 21 ++++++++++--------- .../xpenatan/jparser/idl/IDLAttribute.java | 2 +- .../github/xpenatan/jparser/idl/IDLClass.java | 2 +- .../xpenatan/jparser/idl/IDLMethod.java | 7 ++++++- .../xpenatan/jparser/idl/IDLParameter.java | 2 +- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index aa061f50..2f2f2d00 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -210,7 +210,7 @@ public CppCodeParser(CppGenerator cppGenerator, IDLReader idlReader, String base public void onIDLConstructorGenerated(JParser jParser, IDLConstructor idlConstructor, ClassOrInterfaceDeclaration classDeclaration, ConstructorDeclaration constructorDeclaration, MethodDeclaration nativeMethodDeclaration) { IDLClass idlClass = idlConstructor.idlClass; - String classTypeName = idlClass.getName(); + String classTypeName = idlClass.getCPPName(); NodeList parameters = constructorDeclaration.getParameters(); ArrayList idParameters = idlConstructor.parameters; @@ -229,7 +229,7 @@ public void onIDLDeConstructorGenerated(JParser jParser, IDLClass idlClass, Clas String classTypeName; if(idlClass.callbackImpl == null) { - classTypeName = idlClass.classHeader.prefixName + classDeclaration.getNameAsString(); + classTypeName = idlClass.getCPPName(); } else { classTypeName = idlClass.callbackImpl.name; @@ -254,7 +254,7 @@ public void onIDLAttributeGenerated(JParser jParser, IDLAttribute idlAttribute, String classTypeName = classDeclaration.getNameAsString(); IDLClass idlClass = idlAttribute.idlFile.getClass(classTypeName); if(idlClass != null) { - classTypeName = idlClass.classHeader.prefixName + classTypeName; + classTypeName = idlClass.getCPPName(); } String getPrimitiveCast = ""; @@ -266,7 +266,7 @@ public void onIDLAttributeGenerated(JParser jParser, IDLAttribute idlAttribute, IDLClass retTypeClass = idlAttribute.idlFile.getClass(attributeType); if(retTypeClass != null) { - attributeType = retTypeClass.classHeader.prefixName + attributeType; + attributeType = retTypeClass.getCPPName(); } String attributeReturnCast = ""; @@ -433,7 +433,7 @@ private void generateCPPClass(IDLClass idlClass, ClassOrInterfaceDeclaration cla String callbackCode = generateSetupCallbackMethod(idlClass, callbackDeclaration, methods); String methodsCode = generateMethodCallers(idlClass, methods); cppClass += "" + - "class " + callback.name + " : public " + idlClass.name + " {\n" + + "class " + callback.getCPPName() + " : public " + idlClass.getCPPName() + " {\n" + "private:\n" + "\tJNIEnv* env;\n" + "\tjobject obj;\n" + @@ -644,11 +644,12 @@ private String getCPPType(String typeString) { private void setupMethodGenerated(IDLMethod idlMethod, String param, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, MethodDeclaration nativeMethod) { Type returnType = methodDeclaration.getType(); String returnTypeStr = idlMethod.getJavaReturnType(); + String cppReturnType = idlMethod.getCPPReturnType(); String methodName = idlMethod.name; String classTypeName = classDeclaration.getNameAsString(); IDLClass idlClass = idlMethod.idlFile.getClass(classTypeName); if(idlClass != null) { - classTypeName = idlClass.classHeader.prefixName + classTypeName; + classTypeName = idlClass.getCPPName(); } String returnCastStr = ""; String methodCaller = methodName + "(" + param + ")"; @@ -689,7 +690,7 @@ private void setupMethodGenerated(IDLMethod idlMethod, String param, ClassOrInte String returnTypeName = returnType.asClassOrInterfaceType().asClassOrInterfaceType().getNameAsString(); IDLClass retTypeClass = idlMethod.idlFile.getClass(returnTypeName); if(retTypeClass != null) { - returnTypeName = retTypeClass.classHeader.prefixName + returnTypeName; + returnTypeName = retTypeClass.getCPPName(); } String copyParam = "copy_addr"; content = METHOD_GET_OBJ_VALUE_STATIC_TEMPLATE @@ -703,7 +704,7 @@ private void setupMethodGenerated(IDLMethod idlMethod, String param, ClassOrInte String returnTypeName = returnType.asClassOrInterfaceType().asClassOrInterfaceType().getNameAsString(); IDLClass retTypeClass = idlMethod.idlFile.getClass(returnTypeName); if(retTypeClass != null) { - returnTypeName = retTypeClass.classHeader.prefixName + returnTypeName; + returnTypeName = retTypeClass.getCPPName(); } String copyParam = "copy_addr"; if(operator.isEmpty()) { @@ -726,7 +727,7 @@ private void setupMethodGenerated(IDLMethod idlMethod, String param, ClassOrInte content = METHOD_GET_OBJ_POINTER_STATIC_TEMPLATE.replace(TEMPLATE_TAG_METHOD, methodCaller).replace(TEMPLATE_TAG_TYPE, classTypeName); break; case GET_OBJ_POINTER: - content = METHOD_GET_OBJ_POINTER_TEMPLATE.replace(TEMPLATE_TAG_METHOD, methodCaller).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_RETURN_TYPE, returnTypeStr).replace(TEMPLATE_TAG_CONST, constTag); + content = METHOD_GET_OBJ_POINTER_TEMPLATE.replace(TEMPLATE_TAG_METHOD, methodCaller).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_RETURN_TYPE, cppReturnType).replace(TEMPLATE_TAG_CONST, constTag); break; case GET_PRIMITIVE_STATIC: content = METHOD_GET_PRIMITIVE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_METHOD, methodCaller).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_CAST, returnCastStr); @@ -791,7 +792,7 @@ private static String getParam(IDLFile idlFile, Type type, String paramName, Str } else { if(paramClass != null) { - classType = paramClass.getName(); + classType = paramClass.getCPPName(); } if(isRef || isValue) { paramName = "*((" + classType + "* )" + paramName + ")"; diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java index 74171d4b..205aa80f 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java @@ -70,7 +70,7 @@ public String getCPPType() { String fullType = idlType; if(idlClassOrEnum != null && idlClassOrEnum.isClass()) { IDLClass aClass = idlClassOrEnum.asClass(); - fullType = aClass.getName(); + fullType = aClass.getCPPName(); } return IDLHelper.getCPPReturnType(fullType).replace("[]", ""); } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java index 5c241cca..b5541151 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java @@ -134,7 +134,7 @@ else if(endsWith) { return null; } - public String getName() { + public String getCPPName() { return classHeader.prefixName + name; } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java index 89b6b6b0..d476d6d0 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java @@ -89,7 +89,12 @@ public void initMethod(String line) { } public String getCPPReturnType() { - return IDLHelper.getCPPReturnType(returnType); + String fullType = returnType; + if(returnClassType != null && returnClassType.isClass()) { + IDLClass aClass = returnClassType.asClass(); + fullType = aClass.getCPPName(); + } + return IDLHelper.getCPPReturnType(fullType); } public String getJavaReturnType() { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java index e04c5eaf..6e1ac994 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLParameter.java @@ -82,7 +82,7 @@ public String getCPPType() { String fullType = idlType; if(idlClassOrEnum != null && idlClassOrEnum.isClass()) { IDLClass aClass = idlClassOrEnum.asClass(); - fullType = aClass.getName(); + fullType = aClass.getCPPName(); } return IDLHelper.getCPPReturnType(fullType); } From 148848b76d5f63692fbbc4ca9d61503f908d3840 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 4 Mar 2025 13:33:03 -0300 Subject: [PATCH 147/186] Change dispose to protected and only override it if its not NoDelete --- .../xpenatan/jparser/idl/parser/IDLDeConstructorParser.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java index 4209202e..d5e2c3d8 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java @@ -20,6 +20,9 @@ public class IDLDeConstructorParser { public static void generateDeConstructor(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classOrInterfaceDeclaration, IDLClass idlClass) { if(!idlClass.classHeader.isNoDelete) { + MethodDeclaration disposeMethod = classOrInterfaceDeclaration.addMethod("dispose", Modifier.Keyword.PUBLIC); + disposeMethod.getBody().get().addStatement(new MethodCallExpr("super.dispose")); + List methodsBySignature = classOrInterfaceDeclaration.getMethodsBySignature(DELETE_NATIVE); int size = methodsBySignature.size(); From b6669d7b1121d754243798c6112d6fb90cb6163e Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 4 Mar 2025 14:06:44 -0300 Subject: [PATCH 148/186] Change dispose to protected --- jParser/base/src/main/java/idl/IDLBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jParser/base/src/main/java/idl/IDLBase.java b/jParser/base/src/main/java/idl/IDLBase.java index c15809b5..64f622b3 100644 --- a/jParser/base/src/main/java/idl/IDLBase.java +++ b/jParser/base/src/main/java/idl/IDLBase.java @@ -32,7 +32,7 @@ public boolean isDisposed() { return nativeData.isDisposed(); } - public void dispose() { + protected void dispose() { nativeData.dispose(); } From a1651b5132e57238c1b51664fcabdaa5235e3172 Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 4 Mar 2025 21:01:06 -0300 Subject: [PATCH 149/186] Add bindTo support --- .../xpenatan/jparser/cpp/CppCodeParser.java | 6 +-- .../github/xpenatan/jparser/idl/IDLClass.java | 2 +- .../xpenatan/jparser/idl/IDLMethod.java | 39 +++++++++++++++++-- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index 2f2f2d00..10b1623d 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -501,7 +501,7 @@ else if(type.isClassOrInterfaceType()) { paramCode = "(" + paramCode + ")" + JNITypeSignature.getJNIType(returnTypeStr); - String methodName = idlMethod.name + methodCode; + String methodName = idlMethod.getCPPName() + methodCode; String variable = variableTemplate.replace("[METHOD]", methodName); String methodId = methodIdTemplate.replace("[METHOD]", methodName) @@ -564,7 +564,7 @@ private String generateMethodCallers(IDLClass idlClass, ArrayList parameters = new ArrayList<>(); @@ -42,18 +43,28 @@ public void initMethod(String line) { String tagsStr = IDLHelper.getTags(leftSide); if(!tagsStr.isEmpty()) { - isReturnRef = tagsStr.contains("Ref"); - isReturnValue = tagsStr.contains("Value"); - isReturnConst = tagsStr.contains("Const"); leftSide = leftSide.replace(tagsStr, "").trim(); - tagsStr = tagsStr.substring(1, tagsStr.length()-1); for(String s : tagsStr.split(",")) { + s = s.trim(); if(s.contains("Operator")) { int first = s.indexOf("\""); int last = s.lastIndexOf("\""); operator = s.substring(first, last + 1).replace("\"", ""); } + else if(s.equals("Ref")) { + isReturnRef = true; + } + else if(s.equals("Value")) { + isReturnValue = true; + } + else if(s.equals("Const")) { + isReturnConst = true; + } + else if(s.startsWith("BindTo")) { + s = s.replace("\"", ""); + bindsToName = s.split("=")[1]; + } } } @@ -118,6 +129,25 @@ public void removeLastParam(int count) { } } + public boolean nameEquals(String value) { + if(bindsToName != null) { + if(value.equals(bindsToName)) { + return true; + } + } + else { + return value.equals(name); + } + return false; + } + + public String getCPPName() { + if(bindsToName != null) { + return bindsToName; + } + return name; + } + public IDLMethod clone() { IDLMethod cloned = new IDLMethod(idlClass, idlFile); cloned.line = line; @@ -126,6 +156,7 @@ public IDLMethod clone() { cloned.name = name; cloned.skip = skip; cloned.isAny = isAny; + cloned.bindsToName = bindsToName; cloned.isReturnValue = isReturnValue; cloned.isReturnArray = isReturnArray; cloned.isStaticMethod = isStaticMethod; From e48cffbab85dd64ac14689be8b224495f214275c Mon Sep 17 00:00:00 2001 From: Natan Date: Tue, 4 Mar 2025 22:16:49 -0300 Subject: [PATCH 150/186] add NewObject option for methods so a new object is created every call --- .../xpenatan/jparser/idl/IDLMethod.java | 4 ++ .../idl/parser/IDLAttributeParser.java | 2 +- .../jparser/idl/parser/IDLMethodParser.java | 38 +++++++++++++------ 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java index f9596b43..38413234 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java @@ -20,6 +20,7 @@ public class IDLMethod { public boolean isReturnRef; public boolean isReturnValue; public boolean isReturnConst; + public boolean isReturnNewObject; public boolean isStaticMethod = false; public String operator = ""; public String bindsToName = null; @@ -65,6 +66,9 @@ else if(s.startsWith("BindTo")) { s = s.replace("\"", ""); bindsToName = s.split("=")[1]; } + else if(s.startsWith("NewObject")) { + isReturnNewObject = true; + } } } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java index 9f68b857..4f7e5c97 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java @@ -142,7 +142,7 @@ private static void setupAttributeMethod(IDLDefaultCodeParser idlParser, JParser // When it's a get attribute method we pass a temp c++ object to copy to the returned temp c++ object. } isValue = false; - MethodDeclaration nativeMethod = IDLMethodParser.prepareNativeMethod(idlAttribute.isStatic, isValue, classDeclaration, methodDeclaration, methodName, "", null); + MethodDeclaration nativeMethod = IDLMethodParser.prepareNativeMethod(idlAttribute.isStatic, isValue, false, classDeclaration, methodDeclaration, methodName, "", null); if(nativeMethod != null) { idlParser.onIDLAttributeGenerated(jParser, idlAttribute, isSet, classDeclaration, methodDeclaration, nativeMethod); } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java index eba11774..2276250e 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java @@ -47,6 +47,15 @@ public class IDLMethodParser { " return [TYPE]_TEMP_GEN_[NUM];\n" + "}"; + static final String GET_NEW_OBJECT_TEMPLATE = + "{\n" + + " long pointer = [METHOD];\n" + + " if(pointer == 0) return null;\n" + + " [TYPE] [TYPE]_NEW = new [TYPE]((byte)1, (char)1);\n" + + " [TYPE]_NEW.initNative(pointer, true);\n" + + " return [TYPE]_NEW;\n" + + "}"; + static final String CALLBACK_PARAM_TEMPLATE = "if([TYPE]_TEMP_GEN_[NUM] == null) [TYPE]_TEMP_GEN_[NUM] = new [TYPE]((byte)1, (char)1);\n" + "[TYPE]_TEMP_GEN_[NUM].setCPointer([PARAM]);\n"; @@ -161,13 +170,13 @@ public static boolean canGenerateMethod(MethodDeclaration containsMethod) { } private static void setupMethod(IDLDefaultCodeParser idlParser, JParser jParser, IDLMethod idlMethod, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration) { - MethodDeclaration nativeMethodDeclaration = IDLMethodParser.prepareNativeMethod(idlMethod.isStaticMethod, idlMethod.isReturnValue, classDeclaration, methodDeclaration, idlMethod.name, idlMethod.operator, idlMethod.parameters); + MethodDeclaration nativeMethodDeclaration = IDLMethodParser.prepareNativeMethod(idlMethod.isStaticMethod, idlMethod.isReturnValue, idlMethod.isReturnNewObject, classDeclaration, methodDeclaration, idlMethod.name, idlMethod.operator, idlMethod.parameters); if(nativeMethodDeclaration != null) { idlParser.onIDLMethodGenerated(jParser, idlMethod, classDeclaration, methodDeclaration, nativeMethodDeclaration); } } - public static MethodDeclaration prepareNativeMethod(boolean isStatic, boolean isReturnValue, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, String methodName, String operator, ArrayList idlParameters) { + public static MethodDeclaration prepareNativeMethod(boolean isStatic, boolean isReturnValue, boolean isReturnNewObject, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, String methodName, String operator, ArrayList idlParameters) { NodeList methodParameters = methodDeclaration.getParameters(); Type methodReturnType = methodDeclaration.getType(); MethodDeclaration nativeMethodDeclaration = generateNativeMethod(methodName, methodParameters, methodReturnType, methodDeclaration.isStatic()); @@ -187,7 +196,7 @@ public static MethodDeclaration prepareNativeMethod(boolean isStatic, boolean is else if(methodReturnType.isClassOrInterfaceType()) { // Class object needs to generate some additional code. // Needs to obtain the pointer and return a temp object. - BlockStmt blockStmt = IDLMethodParser.generateTempObjects(isReturnValue, classDeclaration, methodDeclaration, nativeMethodDeclaration, caller, operator, idlParameters); + BlockStmt blockStmt = IDLMethodParser.generateTempObjects(isReturnValue, isReturnNewObject, classDeclaration, methodDeclaration, nativeMethodDeclaration, caller, operator, idlParameters); methodDeclaration.setBody(blockStmt); } else { @@ -246,7 +255,7 @@ else if(type.isArrayType()) { } } - private static BlockStmt generateTempObjects(boolean isReturnValue, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, MethodDeclaration nativeMethodDeclaration, MethodCallExpr caller, String operator, ArrayList idlParameters) { + private static BlockStmt generateTempObjects(boolean isReturnValue, boolean isReturnNewObject, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, MethodDeclaration nativeMethodDeclaration, MethodCallExpr caller, String operator, ArrayList idlParameters) { Type methodReturnType = methodDeclaration.getType(); String className = classDeclaration.getNameAsString(); String returnTypeName = methodReturnType.toString(); @@ -260,10 +269,7 @@ private static BlockStmt generateTempObjects(boolean isReturnValue, ClassOrInter // if its operator and return type is same as class name don't create temp object isRetSameAsClass = true; } - String fieldName = ""; - if(!isRetSameAsClass) { - fieldName = generateFieldName(classDeclaration, returnTypeName, isStatic); - } + IDLMethodParser.setupCallerParam(isStatic, isReturnValue, caller, methodDeclaration.getParameters(), idlParameters); @@ -274,10 +280,18 @@ private static BlockStmt generateTempObjects(boolean isReturnValue, ClassOrInter .replace(TEMPLATE_TAG_METHOD, methodCaller); } else { - newBody = GET_OBJECT_TEMPLATE - .replace(TEMPLATE_TAG_METHOD, methodCaller) - .replace(TEMPLATE_TEMP_FIELD, fieldName) - .replace(TEMPLATE_TAG_TYPE, returnTypeName); + if(isReturnNewObject) { + newBody = GET_NEW_OBJECT_TEMPLATE + .replace(TEMPLATE_TAG_METHOD, methodCaller) + .replace(TEMPLATE_TAG_TYPE, returnTypeName); + } + else { + String fieldName = generateFieldName(classDeclaration, returnTypeName, isStatic);; + newBody = GET_OBJECT_TEMPLATE + .replace(TEMPLATE_TAG_METHOD, methodCaller) + .replace(TEMPLATE_TEMP_FIELD, fieldName) + .replace(TEMPLATE_TAG_TYPE, returnTypeName); + } } BlockStmt body = null; From 8f0bc8fc4ff30d179b76411ae8c1554f4bc5932d Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 5 Mar 2025 15:06:48 -0300 Subject: [PATCH 151/186] Add operator support when returning a primitive --- .../xpenatan/jparser/cpp/CppCodeParser.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java index 10b1623d..c037d2c9 100644 --- a/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java +++ b/jParser/cpp/src/main/java/com/github/xpenatan/jparser/cpp/CppCodeParser.java @@ -153,7 +153,6 @@ public class CppCodeParser extends IDLDefaultCodeParser { "[COPY_PARAM] = [OPERATOR];\n" + "return (jlong)&[COPY_PARAM];"; - protected static final String METHOD_GET_OBJ_VALUE_STATIC_TEMPLATE = "\nstatic [COPY_TYPE] [COPY_PARAM];\n" + "[COPY_PARAM] = [TYPE]::[METHOD];\n" + @@ -192,6 +191,10 @@ public class CppCodeParser extends IDLDefaultCodeParser { "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + "return [CAST]nativeObject->[METHOD];\n"; + protected static final String METHOD_GET_PRIMITIVE_OPERATOR_TEMPLATE = + "\n[TYPE]* nativeObject = ([TYPE]*)this_addr;\n" + + "return ([OPERATOR]);"; + protected static final String ENUM_GET_INT_TEMPLATE = "\nreturn (jlong)[ENUM];\n"; @@ -732,8 +735,16 @@ private void setupMethodGenerated(IDLMethod idlMethod, String param, ClassOrInte case GET_PRIMITIVE_STATIC: content = METHOD_GET_PRIMITIVE_STATIC_TEMPLATE.replace(TEMPLATE_TAG_METHOD, methodCaller).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_CAST, returnCastStr); break; - case GET_PRIMITIVE: - content = METHOD_GET_PRIMITIVE_TEMPLATE.replace(TEMPLATE_TAG_METHOD, methodCaller).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_CAST, returnCastStr); + case GET_PRIMITIVE: { + if(operator.isEmpty()) { + content = METHOD_GET_PRIMITIVE_TEMPLATE.replace(TEMPLATE_TAG_METHOD, methodCaller).replace(TEMPLATE_TAG_TYPE, classTypeName).replace(TEMPLATE_TAG_CAST, returnCastStr); + } + else { + content = METHOD_GET_PRIMITIVE_OPERATOR_TEMPLATE + .replace(TEMPLATE_TAG_OPERATOR, operator) + .replace(TEMPLATE_TAG_TYPE, classTypeName); + } + } break; } @@ -746,7 +757,7 @@ private static String getOperator(String operatorCode, String param) { String oper = ""; if(!operatorCode.isEmpty()) { if(operatorCode.equals("[]")) { - oper = "nativeObject[" + param + "]"; + oper = "(*nativeObject)[" + param + "]"; } else { oper = "(*nativeObject " + operatorCode + " " + param + ")"; From e3532496a68c5e8886922b1450b9c069f5796257 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 6 Mar 2025 08:33:46 -0300 Subject: [PATCH 152/186] Remove ref counting and destroy logic. Improve memory leak detection. --- .../xpenatan/jparser/example/app/TestLib.java | 4 + jParser/base/src/main/java/idl/IDLBase.java | 1 - .../base/src/main/java/idl/IDLNativeData.java | 85 +++++-------------- 3 files changed, 25 insertions(+), 65 deletions(-) diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java index 3006cc7b..0ef86dca 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java @@ -340,6 +340,7 @@ public int onIntCallback(int intValue01, int intValue02) { if(!(value == 7)) { throw new RuntimeException("value == 7"); } + callback.dispose(); } catch(Throwable e) { e.printStackTrace(); test.dispose(); @@ -681,6 +682,9 @@ private static boolean testOperatorClass() { throw new RuntimeException("testOperatorClass '/' !(value == 10)"); } } + operatorClass.dispose(); + otherOPClass.dispose(); + return true; } catch(Throwable e) { e.printStackTrace(); diff --git a/jParser/base/src/main/java/idl/IDLBase.java b/jParser/base/src/main/java/idl/IDLBase.java index 64f622b3..30787008 100644 --- a/jParser/base/src/main/java/idl/IDLBase.java +++ b/jParser/base/src/main/java/idl/IDLBase.java @@ -5,7 +5,6 @@ */ public abstract class IDLBase { - public static boolean USE_REF_COUNTING = false; public static boolean ENABLE_LOGGING = true; protected final IDLNativeData nativeData = new IDLNativeData(this); diff --git a/jParser/base/src/main/java/idl/IDLNativeData.java b/jParser/base/src/main/java/idl/IDLNativeData.java index b92a8e69..54aa3c6f 100644 --- a/jParser/base/src/main/java/idl/IDLNativeData.java +++ b/jParser/base/src/main/java/idl/IDLNativeData.java @@ -6,8 +6,6 @@ public class IDLNativeData { private long cPointer; private boolean cMemOwn; private boolean disposed; - private boolean destroyed; - private int refCount; public IDLNativeData(IDLBase idlBase) { this.idlBase = idlBase; @@ -31,36 +29,10 @@ public void setCPointer(long cPtr) { } } - /** - * Obtains a reference to this object, call release to free the reference. - */ - public void obtain() { - refCount++; - } - - /** - * Release a previously obtained reference, causing the object to be disposed when this was the last reference. - */ - public void release() { - if(--refCount <= 0 && IDLBase.USE_REF_COUNTING) dispose(); - } - - /** - * @return Whether this instance is obtained using the {@link #obtain()} method. - */ - public boolean isObtained() { - return refCount > 0; - } - - protected void construct() { - destroyed = false; - } - public void reset(long cPtr, boolean cMemoryOwn) { - if(!destroyed) destroy(); + dispose(); cMemOwn = cMemoryOwn; cPointer = cPtr; - construct(); } @Override @@ -103,14 +75,24 @@ public boolean hasOwnership() { } public void dispose() { - if(refCount > 0 && IDLBase.USE_REF_COUNTING && IDLBase.ENABLE_LOGGING) { - error("IDL", "Disposing " + toString() + " while it still has " + refCount + " references."); - } if(cMemOwn) { - // Don't try to delete if this object did not create the pointer - disposed = true; - idlBase.deleteNative(); - cPointer = 0; + if(!disposed) { + if(cPointer != 0) { + disposed = true; + idlBase.deleteNative(); + cPointer = 0; + } + else { + if(IDLBase.ENABLE_LOGGING) { + error("IDL", "Disposing error - " + toString() + " cPointer is 0"); + } + } + } + else { + if(IDLBase.ENABLE_LOGGING) { + error("IDL", "Disposing error - " + toString() + " is already disposed"); + } + } } } @@ -126,28 +108,10 @@ public String toString() { return getClass().getSimpleName() + "(" + cPointer + "," + cMemOwn + ")"; } - public void destroy() { - try { - if(destroyed && IDLBase.ENABLE_LOGGING) { - error("IDL", "Already destroyed " + toString()); - } - destroyed = true; - - if(cMemOwn && !disposed) { - if(IDLBase.ENABLE_LOGGING) { - error("IDL", "Disposing " + toString() + " due to garbage collection."); - } - dispose(); - } - } catch(Throwable e) { - error("IDL", "Exception while destroying " + toString(), e); - } - } - @Override protected void finalize() throws Throwable { - if(!destroyed && IDLBase.ENABLE_LOGGING) { - error("IDL", "The " + getClass().getSimpleName() + " class does not override the finalize method."); + if(cMemOwn && !disposed && IDLBase.ENABLE_LOGGING) { + error("IDL", " Memory Leak - " + idlBase.getClass().getSimpleName() + " was not disposed correctly."); } super.finalize(); } @@ -156,13 +120,6 @@ protected void finalize() throws Throwable { * Logs an error message to the console or logcat */ public static void error(String tag, String message) { - //TODO impl - } - - /** - * Logs an error message to the console or logcat - */ - public static void error(String tag, String message, Throwable exception) { - //TODO impl + System.err.println(tag + ": " + message); } } From 5ce0ecc65985e1f58c612e3e884262618bf32562 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 6 Mar 2025 09:42:31 -0300 Subject: [PATCH 153/186] add takeOwnership and releaseOwnership --- jParser/base/src/main/java/idl/IDLBase.java | 8 ++++++++ jParser/base/src/main/java/idl/IDLNativeData.java | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/jParser/base/src/main/java/idl/IDLBase.java b/jParser/base/src/main/java/idl/IDLBase.java index 30787008..ae607c31 100644 --- a/jParser/base/src/main/java/idl/IDLBase.java +++ b/jParser/base/src/main/java/idl/IDLBase.java @@ -46,6 +46,14 @@ public String toString() { protected void deleteNative() { } + public void takeOwnership() { + nativeData.takeOwnership(); + } + + public void releaseOwnership() { + nativeData.releaseOwnership(); + } + /*[-TEAVM;-REPLACE] @org.teavm.jso.JSBody(params = { "addr" }, script = "return [MODULE].UTF8ToString(addr);") public static native String getJSString(int addr); diff --git a/jParser/base/src/main/java/idl/IDLNativeData.java b/jParser/base/src/main/java/idl/IDLNativeData.java index 54aa3c6f..ab812b1e 100644 --- a/jParser/base/src/main/java/idl/IDLNativeData.java +++ b/jParser/base/src/main/java/idl/IDLNativeData.java @@ -53,14 +53,14 @@ public long getCPointer() { } /** - * Take ownership of the native instance, causing the native object to be deleted when this object gets out of scope. + * Take ownership of the native instance, causing the native object to be warned when this object gets out of scope. */ public void takeOwnership() { cMemOwn = true; } /** - * Release ownership of the native instance, causing the native object NOT to be deleted when this object gets out of + * Release ownership of the native instance, causing the native object NOT to be warned when this object gets out of * scope. */ public void releaseOwnership() { From 33caf2ba1705d4b2901b691c4e108cd848633bf4 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 6 Mar 2025 09:47:38 -0300 Subject: [PATCH 154/186] add hasOwnership --- jParser/base/src/main/java/idl/IDLBase.java | 4 ++++ jParser/base/src/main/java/idl/IDLNativeData.java | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/jParser/base/src/main/java/idl/IDLBase.java b/jParser/base/src/main/java/idl/IDLBase.java index ae607c31..c4694f5a 100644 --- a/jParser/base/src/main/java/idl/IDLBase.java +++ b/jParser/base/src/main/java/idl/IDLBase.java @@ -54,6 +54,10 @@ public void releaseOwnership() { nativeData.releaseOwnership(); } + public boolean hasOwnership() { + return nativeData.hasOwnership(); + } + /*[-TEAVM;-REPLACE] @org.teavm.jso.JSBody(params = { "addr" }, script = "return [MODULE].UTF8ToString(addr);") public static native String getJSString(int addr); diff --git a/jParser/base/src/main/java/idl/IDLNativeData.java b/jParser/base/src/main/java/idl/IDLNativeData.java index ab812b1e..38ccb939 100644 --- a/jParser/base/src/main/java/idl/IDLNativeData.java +++ b/jParser/base/src/main/java/idl/IDLNativeData.java @@ -67,9 +67,6 @@ public void releaseOwnership() { cMemOwn = false; } - /** - * @return True if the native is destroyed when this object gets out of scope, false otherwise. - */ public boolean hasOwnership() { return cMemOwn; } From 9137e21721918d51b07646ae91ee870707c3a0cb Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 6 Mar 2025 09:48:15 -0300 Subject: [PATCH 155/186] Revert code. There is already a native method object --- jParser/base/src/main/java/idl/IDLBase.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/jParser/base/src/main/java/idl/IDLBase.java b/jParser/base/src/main/java/idl/IDLBase.java index c4694f5a..30787008 100644 --- a/jParser/base/src/main/java/idl/IDLBase.java +++ b/jParser/base/src/main/java/idl/IDLBase.java @@ -46,18 +46,6 @@ public String toString() { protected void deleteNative() { } - public void takeOwnership() { - nativeData.takeOwnership(); - } - - public void releaseOwnership() { - nativeData.releaseOwnership(); - } - - public boolean hasOwnership() { - return nativeData.hasOwnership(); - } - /*[-TEAVM;-REPLACE] @org.teavm.jso.JSBody(params = { "addr" }, script = "return [MODULE].UTF8ToString(addr);") public static native String getJSString(int addr); From f5445ad744e374c4715c121a0207cbe61dfc6306 Mon Sep 17 00:00:00 2001 From: Natan Date: Fri, 7 Mar 2025 23:18:18 -0300 Subject: [PATCH 156/186] Add custom method command --- .../xpenatan/jparser/idl/IDLAttribute.java | 7 ++- .../github/xpenatan/jparser/idl/IDLClass.java | 57 +++++++++++++++---- .../github/xpenatan/jparser/idl/IDLLine.java | 50 ++++++++++++++++ .../xpenatan/jparser/idl/IDLMethod.java | 16 +++--- .../xpenatan/jparser/idl/IDLReader.java | 6 +- .../idl/parser/IDLAttributeParser.java | 2 +- .../jparser/idl/parser/IDLMethodParser.java | 13 +++-- 7 files changed, 122 insertions(+), 29 deletions(-) create mode 100644 jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLLine.java diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java index 205aa80f..32fbc250 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLAttribute.java @@ -5,7 +5,7 @@ */ public class IDLAttribute { public IDLFile idlFile; - public String line; + public IDLLine idlLine; public String idlType; public String name; public boolean skip = false; @@ -21,8 +21,9 @@ public IDLAttribute(IDLFile idlFile) { this.idlFile = idlFile; } - public void initAttribute(String line) { - this.line = line; + public void initAttribute(IDLLine idlLine) { + this.idlLine = idlLine; + String line = idlLine.line; String[] split = line.split("attribute"); String leftSide = split[0].trim(); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java index 3136af70..1e3f50ae 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLClass.java @@ -11,7 +11,7 @@ public class IDLClass extends IDLClassOrEnum { public IDLClassHeader classHeader; public String extendClass = ""; - public final ArrayList classLines = new ArrayList<>(); + public final ArrayList classLines = new ArrayList<>(); public final ArrayList constructors = new ArrayList<>(); public final ArrayList methods = new ArrayList<>(); public final ArrayList attributes = new ArrayList<>(); @@ -26,19 +26,54 @@ public IDLClass(IDLFile idlFile) { } public void initClass(ArrayList lines) { - classLines.addAll(lines); + setupLines(lines); setupHeader(); setupInterfaceName(); setupExtendClass(); setupAttributesAndMethods(); } + private void setupLines(ArrayList lines) { + for(int i = 0; i < lines.size(); i++) { + String originalLine = lines.get(i); + int commentIndex = originalLine.indexOf("//"); + if(commentIndex != -1) { + String command = null; + String code = originalLine.substring(0, commentIndex); + String comment = originalLine.replace(code, "").replace("//", "").trim(); + code = code.trim(); + comment = comment.trim(); + if(comment.isEmpty()) { + comment = null; + } + else { + int startIdx = comment.indexOf("[-"); + int endIdx = comment.indexOf("]"); + if(startIdx != -1 && endIdx != -1 && endIdx > startIdx+2) { + String tempCommand = comment.substring(startIdx, endIdx+1); + comment = comment.replace(tempCommand, "").trim(); + command = tempCommand.trim(); + if(comment.isEmpty()) { + comment = null; + } + } + } + IDLLine idlLine = new IDLLine(code, comment, command); + classLines.add(idlLine); + } + else { + classLines.add(new IDLLine(originalLine, null, null)); + } + } + } + private void setupAttributesAndMethods() { for(int i = 1; i < classLines.size(); i++) { - String line = classLines.get(i); + IDLLine idlLine = classLines.get(i); + String line = idlLine.line; if(line.contains("attribute ")) { IDLAttribute attribute = new IDLAttribute(idlFile); - attribute.initAttribute(line); + attribute.initAttribute(idlLine); attributes.add(attribute); } else { @@ -59,7 +94,7 @@ private void setupAttributesAndMethods() { else { if(line.contains("(") && line.contains(")")) { IDLMethod method = new IDLMethod(this, idlFile); - method.initMethod(line); + method.initMethod(idlLine); methods.add(method); int totalOptionalParams = method.getTotalOptionalParams(); @@ -84,14 +119,15 @@ private void setupInterfaceName() { } private void setupHeader() { - String line = ""; + String code = ""; if(classLines.size() > 0) { - String headerLine = classLines.get(0); + IDLLine idlLine = classLines.get(0); + String headerLine = idlLine.line; if(IDLClassHeader.isLineHeader(headerLine)) { - line = headerLine; + code = headerLine; } } - classHeader = new IDLClassHeader(line, this); + classHeader = new IDLClassHeader(code, this); } private void setupExtendClass() { @@ -113,7 +149,8 @@ private void setupExtendClass() { private String searchLine(String text, boolean startsWith, boolean endsWith) { for(int i = 0; i < classLines.size(); i++) { - String line = classLines.get(i); + IDLLine idlLine = classLines.get(i); + String line = idlLine.line; if(startsWith) { if(line.startsWith(text)) { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLLine.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLLine.java new file mode 100644 index 00000000..7abab5a0 --- /dev/null +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLLine.java @@ -0,0 +1,50 @@ +package com.github.xpenatan.jparser.idl; + +import java.util.ArrayList; + +public class IDLLine { + public static final String CMD_NEW_OBJECT = "NEW_OBJECT"; + public static final String CMD_MEM_OWN = "MEM_OWN"; + public static final String CMD_NOT_MEM_OWN = "NOT_MEM_OWN"; + + public final String line; + public final String comment; + public final ArrayList commands = new ArrayList<>(); + + private IDLLine(String code, String comment, ArrayList commands) { + this.line = code; + this.comment = comment; + this.commands.addAll(commands); + } + + public IDLLine(String code, String comment, String command) { + this.line = code; + this.comment = comment; + + if(command != null) { + command = command.replace("[-", "").replace("]", "").trim(); + String[] commands = command.split(","); + for(int i = 0; i < commands.length; i++) { + String cmd = commands[i].trim(); + if(!cmd.isEmpty()) { + this.commands.add(cmd); + } + } + } + } + + public IDLLine copy() { + return new IDLLine(line, comment, commands); + } + + public boolean containsCommand(String command) { + for(int i = 0; i < commands.size(); i++) { + String cmd = commands.get(i); + if(cmd.equals(command)) { + return true; + } + } + + return false; + } +} diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java index 38413234..13e69562 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLMethod.java @@ -9,7 +9,7 @@ public class IDLMethod { public final IDLFile idlFile; public final IDLClass idlClass; - public String line; + public IDLLine idlLine; public String paramsLine; public String returnType; public IDLClassOrEnum returnClassType; @@ -21,6 +21,7 @@ public class IDLMethod { public boolean isReturnValue; public boolean isReturnConst; public boolean isReturnNewObject; + public boolean isReturnMemoryOwned; public boolean isStaticMethod = false; public String operator = ""; public String bindsToName = null; @@ -32,8 +33,9 @@ public IDLMethod(IDLClass idlClass, IDLFile idlFile) { this.idlFile = idlFile; } - public void initMethod(String line) { - this.line = line; + public void initMethod(IDLLine idlLine) { + this.idlLine = idlLine; + String line = idlLine.line; paramsLine = IDLMethod.setParameters(idlFile, line, parameters); for(IDLParameter parameter : parameters) { parameter.idlMethod = this; @@ -42,6 +44,9 @@ public void initMethod(String line) { String leftSide = line.substring(0, index).trim(); leftSide = IDLHelper.removeMultipleSpaces(leftSide.trim()); + isReturnNewObject = idlLine.containsCommand(IDLLine.CMD_NEW_OBJECT); + isReturnMemoryOwned = !idlLine.containsCommand(IDLLine.CMD_NOT_MEM_OWN); + String tagsStr = IDLHelper.getTags(leftSide); if(!tagsStr.isEmpty()) { leftSide = leftSide.replace(tagsStr, "").trim(); @@ -66,9 +71,6 @@ else if(s.startsWith("BindTo")) { s = s.replace("\"", ""); bindsToName = s.split("=")[1]; } - else if(s.startsWith("NewObject")) { - isReturnNewObject = true; - } } } @@ -154,7 +156,7 @@ public String getCPPName() { public IDLMethod clone() { IDLMethod cloned = new IDLMethod(idlClass, idlFile); - cloned.line = line; + cloned.idlLine = idlLine.copy(); cloned.paramsLine = paramsLine; cloned.returnType = returnType; cloned.name = name; diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java index cd6b6e99..5b155fec 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLReader.java @@ -159,8 +159,8 @@ private static void parseFile(IDLFile idlFile, ArrayList classLi ArrayList settings = new ArrayList<>(); int size = idlFile.lines.size(); for(int i = 0; i < size; i++) { - String line = idlFile.lines.get(i).trim(); - line = removeComment(line); + String originalLine = idlFile.lines.get(i).trim(); + String line = removeComment(originalLine); String nextLine = getNextLine(idlFile.lines, i); if(line.isEmpty()) { @@ -206,7 +206,7 @@ private static void parseFile(IDLFile idlFile, ArrayList classLi } if(foundStartClass) { if(!justAdded) { - classLines.add(line); + classLines.add(originalLine); } if(line.endsWith("};")) { String nextL = getNextLine(idlFile.lines, i);; diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java index 4f7e5c97..d42ce091 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java @@ -142,7 +142,7 @@ private static void setupAttributeMethod(IDLDefaultCodeParser idlParser, JParser // When it's a get attribute method we pass a temp c++ object to copy to the returned temp c++ object. } isValue = false; - MethodDeclaration nativeMethod = IDLMethodParser.prepareNativeMethod(idlAttribute.isStatic, isValue, false, classDeclaration, methodDeclaration, methodName, "", null); + MethodDeclaration nativeMethod = IDLMethodParser.prepareNativeMethod(idlAttribute.isStatic, isValue, false, false, classDeclaration, methodDeclaration, methodName, "", null); if(nativeMethod != null) { idlParser.onIDLAttributeGenerated(jParser, idlAttribute, isSet, classDeclaration, methodDeclaration, nativeMethod); } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java index 2276250e..063595b2 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java @@ -52,7 +52,7 @@ public class IDLMethodParser { " long pointer = [METHOD];\n" + " if(pointer == 0) return null;\n" + " [TYPE] [TYPE]_NEW = new [TYPE]((byte)1, (char)1);\n" + - " [TYPE]_NEW.initNative(pointer, true);\n" + + " [TYPE]_NEW.initNative(pointer, [MEM_OWNED]);\n" + " return [TYPE]_NEW;\n" + "}"; @@ -83,6 +83,8 @@ public class IDLMethodParser { static final String TEMPLATE_TAG_NUM = "[NUM]"; + static final String TEMPLATE_TAG_MEM_OWNED = "[MEM_OWNED]"; + public static void generateMethod(IDLDefaultCodeParser idlParser, JParser jParser, CompilationUnit unit, ClassOrInterfaceDeclaration classOrInterfaceDeclaration, IDLClass idlClass, IDLMethod idlMethod) { MethodDeclaration methodDeclaration = generateAndAddMethodOnly(idlParser, jParser, unit, classOrInterfaceDeclaration, idlMethod); if(methodDeclaration != null && idlParser.generateClass) { @@ -170,13 +172,13 @@ public static boolean canGenerateMethod(MethodDeclaration containsMethod) { } private static void setupMethod(IDLDefaultCodeParser idlParser, JParser jParser, IDLMethod idlMethod, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration) { - MethodDeclaration nativeMethodDeclaration = IDLMethodParser.prepareNativeMethod(idlMethod.isStaticMethod, idlMethod.isReturnValue, idlMethod.isReturnNewObject, classDeclaration, methodDeclaration, idlMethod.name, idlMethod.operator, idlMethod.parameters); + MethodDeclaration nativeMethodDeclaration = IDLMethodParser.prepareNativeMethod(idlMethod.isStaticMethod, idlMethod.isReturnValue, idlMethod.isReturnNewObject, idlMethod.isReturnMemoryOwned, classDeclaration, methodDeclaration, idlMethod.name, idlMethod.operator, idlMethod.parameters); if(nativeMethodDeclaration != null) { idlParser.onIDLMethodGenerated(jParser, idlMethod, classDeclaration, methodDeclaration, nativeMethodDeclaration); } } - public static MethodDeclaration prepareNativeMethod(boolean isStatic, boolean isReturnValue, boolean isReturnNewObject, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, String methodName, String operator, ArrayList idlParameters) { + public static MethodDeclaration prepareNativeMethod(boolean isStatic, boolean isReturnValue, boolean isReturnNewObject, boolean isReturnMemOwned, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, String methodName, String operator, ArrayList idlParameters) { NodeList methodParameters = methodDeclaration.getParameters(); Type methodReturnType = methodDeclaration.getType(); MethodDeclaration nativeMethodDeclaration = generateNativeMethod(methodName, methodParameters, methodReturnType, methodDeclaration.isStatic()); @@ -196,7 +198,7 @@ public static MethodDeclaration prepareNativeMethod(boolean isStatic, boolean is else if(methodReturnType.isClassOrInterfaceType()) { // Class object needs to generate some additional code. // Needs to obtain the pointer and return a temp object. - BlockStmt blockStmt = IDLMethodParser.generateTempObjects(isReturnValue, isReturnNewObject, classDeclaration, methodDeclaration, nativeMethodDeclaration, caller, operator, idlParameters); + BlockStmt blockStmt = IDLMethodParser.generateTempObjects(isReturnValue, isReturnNewObject, isReturnMemOwned, classDeclaration, methodDeclaration, nativeMethodDeclaration, caller, operator, idlParameters); methodDeclaration.setBody(blockStmt); } else { @@ -255,7 +257,7 @@ else if(type.isArrayType()) { } } - private static BlockStmt generateTempObjects(boolean isReturnValue, boolean isReturnNewObject, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, MethodDeclaration nativeMethodDeclaration, MethodCallExpr caller, String operator, ArrayList idlParameters) { + private static BlockStmt generateTempObjects(boolean isReturnValue, boolean isReturnNewObject, boolean isReturnMemOwned, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, MethodDeclaration nativeMethodDeclaration, MethodCallExpr caller, String operator, ArrayList idlParameters) { Type methodReturnType = methodDeclaration.getType(); String className = classDeclaration.getNameAsString(); String returnTypeName = methodReturnType.toString(); @@ -283,6 +285,7 @@ private static BlockStmt generateTempObjects(boolean isReturnValue, boolean isRe if(isReturnNewObject) { newBody = GET_NEW_OBJECT_TEMPLATE .replace(TEMPLATE_TAG_METHOD, methodCaller) + .replace(TEMPLATE_TAG_MEM_OWNED, String.valueOf(isReturnMemOwned)) .replace(TEMPLATE_TAG_TYPE, returnTypeName); } else { From 1364397bed80aea27e369465b9af86ba472c9e18 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 9 Mar 2025 10:17:25 -0300 Subject: [PATCH 157/186] Small internal improvements. --- .../idl/parser/IDLAttributeParser.java | 12 ++---- .../idl/parser/IDLConstructorParser.java | 7 +++- .../jparser/idl/parser/IDLMethodParser.java | 37 ++++++++++++------- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java index d42ce091..b4d18a9d 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java @@ -136,13 +136,9 @@ public static void generateAttribute(IDLDefaultCodeParser idlParser, JParser jPa } private static void setupAttributeMethod(IDLDefaultCodeParser idlParser, JParser jParser, IDLAttribute idlAttribute, boolean isSet, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, String methodName) { - boolean isValue = idlAttribute.isValue; - boolean addCopyParam = false; - if(isValue && !isSet) { - // When it's a get attribute method we pass a temp c++ object to copy to the returned temp c++ object. - } - isValue = false; - MethodDeclaration nativeMethod = IDLMethodParser.prepareNativeMethod(idlAttribute.isStatic, isValue, false, false, classDeclaration, methodDeclaration, methodName, "", null); + IDLMethodParser.NativeMethodData methodData = new IDLMethodParser.NativeMethodData(); + methodData.isStatic = idlAttribute.isStatic; + MethodDeclaration nativeMethod = IDLMethodParser.prepareNativeMethod(methodData, classDeclaration, methodDeclaration, methodName, "", null); if(nativeMethod != null) { idlParser.onIDLAttributeGenerated(jParser, idlAttribute, isSet, classDeclaration, methodDeclaration, nativeMethod); } @@ -151,8 +147,6 @@ private static void setupAttributeMethod(IDLDefaultCodeParser idlParser, JParser public static boolean shouldSkipMethod(MethodDeclaration containsMethod) { if(containsMethod != null) { boolean isNative = containsMethod.isNative(); - boolean isStatic = containsMethod.isStatic(); - boolean containsBlockComment = false; Optional optionalComment = containsMethod.getComment(); if(optionalComment.isPresent()) { Comment comment = optionalComment.get(); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java index 65e9ce05..b883fdb1 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java @@ -48,6 +48,8 @@ public static void generateConstructor(IDLDefaultCodeParser idlParser, JParser j ConstructorDeclaration constructorDeclaration = classDeclaration.addConstructor(Modifier.Keyword.PUBLIC); constructorDeclaration.addParameter("byte", "b"); constructorDeclaration.addParameter("char", "c"); + constructorDeclaration.addAnnotation(Deprecated.class); + constructorDeclaration.setJavadocComment("Dummy constructor, used internally to creates objects without C++ pointer"); } } @@ -122,8 +124,9 @@ public static MethodDeclaration setupConstructor(IDLConstructor idlConstructor, MethodCallExpr caller = IDLMethodParser.createCaller(nativeMethod); BlockStmt blockStmt = constructorDeclaration.getBody(); - - IDLMethodParser.setupCallerParam(isStatic, false, caller, parameters, idlConstructor.parameters); + IDLMethodParser.NativeMethodData paramData = new IDLMethodParser.NativeMethodData(); + paramData.isStatic = isStatic; + IDLMethodParser.setupCallerParam(paramData, caller, parameters, idlConstructor.parameters); Statement statement1 = StaticJavaParser.parseStatement("long addr = " + caller + ";"); Statement statement2 = StaticJavaParser.parseStatement("initNative(addr, true);"); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java index 063595b2..4bc4168c 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java @@ -172,13 +172,18 @@ public static boolean canGenerateMethod(MethodDeclaration containsMethod) { } private static void setupMethod(IDLDefaultCodeParser idlParser, JParser jParser, IDLMethod idlMethod, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration) { - MethodDeclaration nativeMethodDeclaration = IDLMethodParser.prepareNativeMethod(idlMethod.isStaticMethod, idlMethod.isReturnValue, idlMethod.isReturnNewObject, idlMethod.isReturnMemoryOwned, classDeclaration, methodDeclaration, idlMethod.name, idlMethod.operator, idlMethod.parameters); + NativeMethodData methodData = new NativeMethodData(); + methodData.isStatic = idlMethod.isStaticMethod; + methodData.isReturnValue = idlMethod.isReturnValue; + methodData.isReturnNewObject = idlMethod.isReturnNewObject; + methodData.isReturnMemOwned = idlMethod.isReturnMemoryOwned; + MethodDeclaration nativeMethodDeclaration = IDLMethodParser.prepareNativeMethod(methodData, classDeclaration, methodDeclaration, idlMethod.name, idlMethod.operator, idlMethod.parameters); if(nativeMethodDeclaration != null) { idlParser.onIDLMethodGenerated(jParser, idlMethod, classDeclaration, methodDeclaration, nativeMethodDeclaration); } } - public static MethodDeclaration prepareNativeMethod(boolean isStatic, boolean isReturnValue, boolean isReturnNewObject, boolean isReturnMemOwned, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, String methodName, String operator, ArrayList idlParameters) { + public static MethodDeclaration prepareNativeMethod(NativeMethodData paramData, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, String methodName, String operator, ArrayList idlParameters) { NodeList methodParameters = methodDeclaration.getParameters(); Type methodReturnType = methodDeclaration.getType(); MethodDeclaration nativeMethodDeclaration = generateNativeMethod(methodName, methodParameters, methodReturnType, methodDeclaration.isStatic()); @@ -191,20 +196,20 @@ public static MethodDeclaration prepareNativeMethod(boolean isStatic, boolean is if(methodReturnType.isVoidType()) { // void types just call the method. - IDLMethodParser.setupCallerParam(isStatic, false, caller, methodDeclaration.getParameters(), idlParameters); + IDLMethodParser.setupCallerParam(paramData, caller, methodDeclaration.getParameters(), idlParameters); BlockStmt blockStmt = methodDeclaration.getBody().get(); blockStmt.addStatement(caller); } else if(methodReturnType.isClassOrInterfaceType()) { // Class object needs to generate some additional code. // Needs to obtain the pointer and return a temp object. - BlockStmt blockStmt = IDLMethodParser.generateTempObjects(isReturnValue, isReturnNewObject, isReturnMemOwned, classDeclaration, methodDeclaration, nativeMethodDeclaration, caller, operator, idlParameters); + BlockStmt blockStmt = IDLMethodParser.generateTempObjects(paramData, classDeclaration, methodDeclaration, caller, operator, idlParameters); methodDeclaration.setBody(blockStmt); } else { // Should be a primitive return type. ReturnStmt returnStmt = IDLMethodParser.getReturnStmt(methodDeclaration); - IDLMethodParser.setupCallerParam(isStatic, false, caller, methodDeclaration.getParameters(), idlParameters); + IDLMethodParser.setupCallerParam(paramData, caller, methodDeclaration.getParameters(), idlParameters); returnStmt.setExpression(caller); } return nativeMethodDeclaration; @@ -219,8 +224,8 @@ public static MethodCallExpr createCaller(MethodDeclaration nativeMethodDeclarat return caller; } - public static void setupCallerParam(boolean isStatic, boolean isReturnValue, MethodCallExpr caller, NodeList methodParameters, ArrayList idlParameters) { - if(!isStatic) { + public static void setupCallerParam(NativeMethodData paramData, MethodCallExpr caller, NodeList methodParameters, ArrayList idlParameters) { + if(!paramData.isStatic) { caller.addArgument("(long)" + IDLDefaultCodeParser.CPOINTER_METHOD); } for(int i = 0; i < methodParameters.size(); i++) { @@ -257,7 +262,7 @@ else if(type.isArrayType()) { } } - private static BlockStmt generateTempObjects(boolean isReturnValue, boolean isReturnNewObject, boolean isReturnMemOwned, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, MethodDeclaration nativeMethodDeclaration, MethodCallExpr caller, String operator, ArrayList idlParameters) { + private static BlockStmt generateTempObjects(NativeMethodData paramData, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, MethodCallExpr caller, String operator, ArrayList idlParameters) { Type methodReturnType = methodDeclaration.getType(); String className = classDeclaration.getNameAsString(); String returnTypeName = methodReturnType.toString(); @@ -267,13 +272,12 @@ private static BlockStmt generateTempObjects(boolean isReturnValue, boolean isRe boolean isRetSameAsClass = false; - if(!operator.isEmpty() && className.equals(returnTypeName) && !isReturnValue) { // is pointer or ref + if(!operator.isEmpty() && className.equals(returnTypeName) && !paramData.isReturnValue) { // is pointer or ref // if its operator and return type is same as class name don't create temp object isRetSameAsClass = true; } - - IDLMethodParser.setupCallerParam(isStatic, isReturnValue, caller, methodDeclaration.getParameters(), idlParameters); + IDLMethodParser.setupCallerParam(paramData, caller, methodDeclaration.getParameters(), idlParameters); String methodCaller = caller.toString(); @@ -282,10 +286,10 @@ private static BlockStmt generateTempObjects(boolean isReturnValue, boolean isRe .replace(TEMPLATE_TAG_METHOD, methodCaller); } else { - if(isReturnNewObject) { + if(paramData.isReturnNewObject) { newBody = GET_NEW_OBJECT_TEMPLATE .replace(TEMPLATE_TAG_METHOD, methodCaller) - .replace(TEMPLATE_TAG_MEM_OWNED, String.valueOf(isReturnMemOwned)) + .replace(TEMPLATE_TAG_MEM_OWNED, String.valueOf(paramData.isReturnMemOwned)) .replace(TEMPLATE_TAG_TYPE, returnTypeName); } else { @@ -455,4 +459,11 @@ private static MethodDeclaration containsMethod(IDLDefaultCodeParser idlParser, return null; } + public static class NativeMethodData { + + public boolean isStatic; + public boolean isReturnValue; + public boolean isReturnNewObject; + public boolean isReturnMemOwned; + } } From 529c220a337734c26764a01e2404c3a4ef6f51de Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 9 Mar 2025 18:55:54 -0300 Subject: [PATCH 158/186] Internal improvements in native methods --- .../xpenatan/jparser/example/app/TestLib.java | 2 +- .../example/testlib/CallbackClassManual.java | 6 ++-- jParser/base/src/main/java/idl/IDLBase.java | 14 +------- .../base/src/main/java/idl/IDLNativeData.java | 13 ------- .../src/main/java/idl/helper/IDLString.java | 4 +-- .../main/java/idl/helper/IDLStringView.java | 2 +- .../idl/parser/IDLAttributeParser.java | 4 +++ .../idl/parser/IDLConstructorParser.java | 2 +- .../idl/parser/IDLDeConstructorParser.java | 4 +++ .../idl/parser/IDLDefaultCodeParser.java | 2 +- .../jparser/idl/parser/IDLMethodParser.java | 34 ++++++++++--------- 11 files changed, 36 insertions(+), 51 deletions(-) diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java index 0ef86dca..751b3db1 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java @@ -189,7 +189,7 @@ private static boolean testMethodClass() { array.setValue(0, obj1); array.setValue(1, obj2); try { - TestMethodClass.native_setMethod07(test.getCPointer(), array.getPointer()); + TestMethodClass.native_setMethod07(test.getNativeData().getCPointer(), array.getPointer()); { float intValue01 = obj1.get_intValue01(); if(!(intValue01 == 20)) { diff --git a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java index 29222a8e..b6b89892 100644 --- a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java +++ b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java @@ -82,7 +82,7 @@ public interface onStringCallback extends org.teavm.jso.JSObject { public CallbackClassManual() { long addr = internal_native_create(); - initNative(addr, true); + nativeData.initNative(addr, true); setupCallbacks(); } @@ -127,11 +127,11 @@ public void onStringCallback(int strValue01) { internal_onStringCallback(IDLBase.getJSString(strValue01)); } }; - internal_native_setupCallbacks((int)getCPointer(), onVoidCallback, onIntCallback, onFloatCallback, onBoolCallback, onStringCallback); + internal_native_setupCallbacks((int)getNativeData().getCPointer(), onVoidCallback, onIntCallback, onFloatCallback, onBoolCallback, onStringCallback); } */ private void setupCallbacks() { - internal_native_setupCallbacks(getCPointer()); + internal_native_setupCallbacks(getNativeData().getCPointer()); } /*[-JNI;-NATIVE] diff --git a/jParser/base/src/main/java/idl/IDLBase.java b/jParser/base/src/main/java/idl/IDLBase.java index 30787008..fa2d847c 100644 --- a/jParser/base/src/main/java/idl/IDLBase.java +++ b/jParser/base/src/main/java/idl/IDLBase.java @@ -11,23 +11,11 @@ public abstract class IDLBase { public IDLBase() { } - public final void initNative(long cPtr, boolean cMemoryOwn) { - nativeData.initNative(cPtr, cMemoryOwn); - } - - public final void setCPointer(long cPtr) { - nativeData.setCPointer(cPtr); - } - - public final long getCPointer() { - return nativeData.getCPointer(); - } - public final IDLNativeData getNativeData() { return nativeData; } - public boolean isDisposed() { + protected boolean isDisposed() { return nativeData.isDisposed(); } diff --git a/jParser/base/src/main/java/idl/IDLNativeData.java b/jParser/base/src/main/java/idl/IDLNativeData.java index 38ccb939..23d3cb04 100644 --- a/jParser/base/src/main/java/idl/IDLNativeData.java +++ b/jParser/base/src/main/java/idl/IDLNativeData.java @@ -16,19 +16,6 @@ public void initNative(long cPtr, boolean cMemoryOwn) { cPointer = cPtr; } - /** - * Set pointer if it's not owned by this object. Useful for setting temp objets - */ - public void setCPointer(long cPtr) { - if(!cMemOwn) { - cPointer = cPtr; - } - else { - String className = getClass().getSimpleName(); - throw new RuntimeException("Cannot change " + className + " pointer owned by native code"); - } - } - public void reset(long cPtr, boolean cMemoryOwn) { dispose(); cMemOwn = cMemoryOwn; diff --git a/jParser/base/src/main/java/idl/helper/IDLString.java b/jParser/base/src/main/java/idl/helper/IDLString.java index 3fbd068a..2a18efbc 100644 --- a/jParser/base/src/main/java/idl/helper/IDLString.java +++ b/jParser/base/src/main/java/idl/helper/IDLString.java @@ -20,7 +20,7 @@ public IDLString() { public IDLString(byte b, char c) {} public String c_str() { - String text = internal_native_c_str(getCPointer()); + String text = internal_native_c_str(getNativeData().getCPointer()); return text; } @@ -38,7 +38,7 @@ public String c_str() { private static native String internal_native_c_str(long this_addr); public String data() { - String text = internal_native_data(getCPointer()); + String text = internal_native_data(getNativeData().getCPointer()); return text; } diff --git a/jParser/base/src/main/java/idl/helper/IDLStringView.java b/jParser/base/src/main/java/idl/helper/IDLStringView.java index 5f5b7721..4f5c5f12 100644 --- a/jParser/base/src/main/java/idl/helper/IDLStringView.java +++ b/jParser/base/src/main/java/idl/helper/IDLStringView.java @@ -20,7 +20,7 @@ public IDLStringView() { public IDLStringView(byte b, char c) {} public String data() { - String text = internal_native_data(getCPointer()); + String text = internal_native_data(getNativeData().getCPointer()); return text; } diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java index b4d18a9d..2e150508 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLAttributeParser.java @@ -138,6 +138,10 @@ public static void generateAttribute(IDLDefaultCodeParser idlParser, JParser jPa private static void setupAttributeMethod(IDLDefaultCodeParser idlParser, JParser jParser, IDLAttribute idlAttribute, boolean isSet, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, String methodName) { IDLMethodParser.NativeMethodData methodData = new IDLMethodParser.NativeMethodData(); methodData.isStatic = idlAttribute.isStatic; + if(idlAttribute.idlClassOrEnum != null && idlAttribute.idlClassOrEnum.isClass()) { + IDLClass aClass = idlAttribute.idlClassOrEnum.asClass(); + methodData.isNoDelete = aClass.classHeader.isNoDelete; + } MethodDeclaration nativeMethod = IDLMethodParser.prepareNativeMethod(methodData, classDeclaration, methodDeclaration, methodName, "", null); if(nativeMethod != null) { idlParser.onIDLAttributeGenerated(jParser, idlAttribute, isSet, classDeclaration, methodDeclaration, nativeMethod); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java index b883fdb1..8546b879 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java @@ -129,7 +129,7 @@ public static MethodDeclaration setupConstructor(IDLConstructor idlConstructor, IDLMethodParser.setupCallerParam(paramData, caller, parameters, idlConstructor.parameters); Statement statement1 = StaticJavaParser.parseStatement("long addr = " + caller + ";"); - Statement statement2 = StaticJavaParser.parseStatement("initNative(addr, true);"); + Statement statement2 = StaticJavaParser.parseStatement("getNativeData().initNative(addr, true);"); blockStmt.addStatement(statement1); blockStmt.addStatement(statement2); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java index d5e2c3d8..24b3e209 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDeConstructorParser.java @@ -8,6 +8,7 @@ import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.expr.MethodCallExpr; import com.github.javaparser.ast.stmt.BlockStmt; +import com.github.javaparser.ast.type.PrimitiveType; import com.github.javaparser.ast.type.Type; import com.github.xpenatan.jparser.core.JParser; import com.github.xpenatan.jparser.core.JParserHelper; @@ -22,6 +23,9 @@ public static void generateDeConstructor(IDLDefaultCodeParser idlParser, JParser if(!idlClass.classHeader.isNoDelete) { MethodDeclaration disposeMethod = classOrInterfaceDeclaration.addMethod("dispose", Modifier.Keyword.PUBLIC); disposeMethod.getBody().get().addStatement(new MethodCallExpr("super.dispose")); + MethodDeclaration isDisposeMethod = classOrInterfaceDeclaration.addMethod("isDisposed", Modifier.Keyword.PUBLIC); + isDisposeMethod.setType(PrimitiveType.booleanType()); + isDisposeMethod.getBody().get().addStatement(new MethodCallExpr("return super.isDisposed")); List methodsBySignature = classOrInterfaceDeclaration.getMethodsBySignature(DELETE_NATIVE); int size = methodsBySignature.size(); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java index 922e18f8..ef26999c 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLDefaultCodeParser.java @@ -37,7 +37,7 @@ public class IDLDefaultCodeParser extends IDLClassGeneratorParser { protected boolean enableAttributeParsing = true; - protected static final String CPOINTER_METHOD = "getCPointer()"; + protected static final String CPOINTER_METHOD = "getNativeData().getCPointer()"; public IDLDefaultCodeParser(String headerCMD, IDLReader idlReader, String cppDir) { super("", headerCMD, idlReader, cppDir); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java index 4bc4168c..aa27ff9a 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java @@ -43,7 +43,7 @@ public class IDLMethodParser { " long pointer = [METHOD];\n" + " if(pointer == 0) return null;\n" + " if([TYPE]_TEMP_GEN_[NUM] == null) [TYPE]_TEMP_GEN_[NUM] = new [TYPE]((byte)1, (char)1);\n" + - " [TYPE]_TEMP_GEN_[NUM].setCPointer(pointer);\n" + + " [TYPE]_TEMP_GEN_[NUM].getNativeData().initNative(pointer, false);\n" + " return [TYPE]_TEMP_GEN_[NUM];\n" + "}"; @@ -52,19 +52,13 @@ public class IDLMethodParser { " long pointer = [METHOD];\n" + " if(pointer == 0) return null;\n" + " [TYPE] [TYPE]_NEW = new [TYPE]((byte)1, (char)1);\n" + - " [TYPE]_NEW.initNative(pointer, [MEM_OWNED]);\n" + + " [TYPE]_NEW.getNativeData().initNative(pointer, [MEM_OWNED]);\n" + " return [TYPE]_NEW;\n" + "}"; static final String CALLBACK_PARAM_TEMPLATE = "if([TYPE]_TEMP_GEN_[NUM] == null) [TYPE]_TEMP_GEN_[NUM] = new [TYPE]((byte)1, (char)1);\n" + - "[TYPE]_TEMP_GEN_[NUM].setCPointer([PARAM]);\n"; - - static final String GET_TEMP_OBJECT_TEMPLATE = - "{\n" + - " [METHOD];\n" + - " return [TYPE]_TEMP_GEN_[NUM];\n" + - "}"; + "[TYPE]_TEMP_GEN_[NUM].getNativeData().initNative([PARAM], false);\n"; static final String OPERATOR_OBJECT_TEMPLATE = "{\n" + @@ -176,7 +170,11 @@ private static void setupMethod(IDLDefaultCodeParser idlParser, JParser jParser, methodData.isStatic = idlMethod.isStaticMethod; methodData.isReturnValue = idlMethod.isReturnValue; methodData.isReturnNewObject = idlMethod.isReturnNewObject; - methodData.isReturnMemOwned = idlMethod.isReturnMemoryOwned; + methodData.isReturnMemoryOwned = idlMethod.isReturnMemoryOwned; + if(idlMethod.returnClassType != null && idlMethod.returnClassType.isClass()) { + IDLClass aClass = idlMethod.returnClassType.asClass(); + methodData.isNoDelete = aClass.classHeader.isNoDelete; + } MethodDeclaration nativeMethodDeclaration = IDLMethodParser.prepareNativeMethod(methodData, classDeclaration, methodDeclaration, idlMethod.name, idlMethod.operator, idlMethod.parameters); if(nativeMethodDeclaration != null) { idlParser.onIDLMethodGenerated(jParser, idlMethod, classDeclaration, methodDeclaration, nativeMethodDeclaration); @@ -245,12 +243,12 @@ public static void setupCallerParam(NativeMethodData paramData, MethodCallExpr c isArray = idlParameter.isArray; } if(isArray && IDLHelper.getCArray(type.asClassOrInterfaceType().getNameAsString()) != null) { - String methodCall = paramName + ".getPointer()"; + String methodCall = paramName + "." + IDLDefaultCodeParser.CPOINTER_METHOD; paramName = "(long)(" + variableName + " != null ? " + methodCall + " : 0)"; } else if(!IDLHelper.isString(type.asClassOrInterfaceType())) { //All methods must contain a base class to get its pointer - String methodCall = paramName + ".getCPointer()"; + String methodCall = paramName + "." + IDLDefaultCodeParser.CPOINTER_METHOD; paramName = "(long)(" + variableName + " != null ? " + methodCall + " : 0)"; } } @@ -269,8 +267,12 @@ private static BlockStmt generateTempObjects(NativeMethodData paramData, ClassOr String newBody = null; boolean isStatic = methodDeclaration.isStatic(); - boolean isRetSameAsClass = false; + boolean isReturnMemOwned = paramData.isReturnMemoryOwned; + if(paramData.isNoDelete) { + // When NoDelete it means that the library is responsible to delete it. + isReturnMemOwned = false; + } if(!operator.isEmpty() && className.equals(returnTypeName) && !paramData.isReturnValue) { // is pointer or ref // if its operator and return type is same as class name don't create temp object @@ -289,7 +291,7 @@ private static BlockStmt generateTempObjects(NativeMethodData paramData, ClassOr if(paramData.isReturnNewObject) { newBody = GET_NEW_OBJECT_TEMPLATE .replace(TEMPLATE_TAG_METHOD, methodCaller) - .replace(TEMPLATE_TAG_MEM_OWNED, String.valueOf(paramData.isReturnMemOwned)) + .replace(TEMPLATE_TAG_MEM_OWNED, String.valueOf(isReturnMemOwned)) .replace(TEMPLATE_TAG_TYPE, returnTypeName); } else { @@ -460,10 +462,10 @@ private static MethodDeclaration containsMethod(IDLDefaultCodeParser idlParser, } public static class NativeMethodData { - public boolean isStatic; public boolean isReturnValue; public boolean isReturnNewObject; - public boolean isReturnMemOwned; + public boolean isReturnMemoryOwned; + public boolean isNoDelete; } } From 90774b0231d7059987abffc60b35ea6bd9ea7f80 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 9 Mar 2025 19:07:52 -0300 Subject: [PATCH 159/186] Remove initNative --- .../jparser/example/testlib/CallbackClassManual.java | 2 +- jParser/base/src/main/java/idl/IDLNativeData.java | 6 +----- .../xpenatan/jparser/idl/parser/IDLConstructorParser.java | 2 +- .../github/xpenatan/jparser/idl/parser/IDLMethodParser.java | 6 +++--- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java index b6b89892..e2d61ac9 100644 --- a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java +++ b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/CallbackClassManual.java @@ -82,7 +82,7 @@ public interface onStringCallback extends org.teavm.jso.JSObject { public CallbackClassManual() { long addr = internal_native_create(); - nativeData.initNative(addr, true); + nativeData.reset(addr, true); setupCallbacks(); } diff --git a/jParser/base/src/main/java/idl/IDLNativeData.java b/jParser/base/src/main/java/idl/IDLNativeData.java index 23d3cb04..11f95cca 100644 --- a/jParser/base/src/main/java/idl/IDLNativeData.java +++ b/jParser/base/src/main/java/idl/IDLNativeData.java @@ -11,15 +11,11 @@ public IDLNativeData(IDLBase idlBase) { this.idlBase = idlBase; } - public void initNative(long cPtr, boolean cMemoryOwn) { - cMemOwn = cMemoryOwn; - cPointer = cPtr; - } - public void reset(long cPtr, boolean cMemoryOwn) { dispose(); cMemOwn = cMemoryOwn; cPointer = cPtr; + disposed = false; } @Override diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java index 8546b879..111b57c2 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java @@ -129,7 +129,7 @@ public static MethodDeclaration setupConstructor(IDLConstructor idlConstructor, IDLMethodParser.setupCallerParam(paramData, caller, parameters, idlConstructor.parameters); Statement statement1 = StaticJavaParser.parseStatement("long addr = " + caller + ";"); - Statement statement2 = StaticJavaParser.parseStatement("getNativeData().initNative(addr, true);"); + Statement statement2 = StaticJavaParser.parseStatement("getNativeData().reset(addr, true);"); blockStmt.addStatement(statement1); blockStmt.addStatement(statement2); diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java index aa27ff9a..d7c5ab39 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java @@ -43,7 +43,7 @@ public class IDLMethodParser { " long pointer = [METHOD];\n" + " if(pointer == 0) return null;\n" + " if([TYPE]_TEMP_GEN_[NUM] == null) [TYPE]_TEMP_GEN_[NUM] = new [TYPE]((byte)1, (char)1);\n" + - " [TYPE]_TEMP_GEN_[NUM].getNativeData().initNative(pointer, false);\n" + + " [TYPE]_TEMP_GEN_[NUM].getNativeData().reset(pointer, false);\n" + " return [TYPE]_TEMP_GEN_[NUM];\n" + "}"; @@ -52,13 +52,13 @@ public class IDLMethodParser { " long pointer = [METHOD];\n" + " if(pointer == 0) return null;\n" + " [TYPE] [TYPE]_NEW = new [TYPE]((byte)1, (char)1);\n" + - " [TYPE]_NEW.getNativeData().initNative(pointer, [MEM_OWNED]);\n" + + " [TYPE]_NEW.getNativeData().reset(pointer, [MEM_OWNED]);\n" + " return [TYPE]_NEW;\n" + "}"; static final String CALLBACK_PARAM_TEMPLATE = "if([TYPE]_TEMP_GEN_[NUM] == null) [TYPE]_TEMP_GEN_[NUM] = new [TYPE]((byte)1, (char)1);\n" + - "[TYPE]_TEMP_GEN_[NUM].getNativeData().initNative([PARAM], false);\n"; + "[TYPE]_TEMP_GEN_[NUM].getNativeData().reset([PARAM], false);\n"; static final String OPERATOR_OBJECT_TEMPLATE = "{\n" + From 6b99235a3e15d4ece5e682f29ab9286ad6e430f2 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 9 Mar 2025 19:11:44 -0300 Subject: [PATCH 160/186] add native reset method by passing IDLBase object --- jParser/base/src/main/java/idl/IDLNativeData.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jParser/base/src/main/java/idl/IDLNativeData.java b/jParser/base/src/main/java/idl/IDLNativeData.java index 11f95cca..d02d0d71 100644 --- a/jParser/base/src/main/java/idl/IDLNativeData.java +++ b/jParser/base/src/main/java/idl/IDLNativeData.java @@ -18,6 +18,10 @@ public void reset(long cPtr, boolean cMemoryOwn) { disposed = false; } + public void reset(IDLBase idlBase, boolean cMemoryOwn) { + reset(idlBase.nativeData.getCPointer(), cMemoryOwn); + } + @Override public boolean equals(Object obj) { return (obj instanceof IDLBase) && (((IDLNativeData)obj).cPointer == this.cPointer); From 4fd1aab924945cd3a116156653a4e95a233c35d8 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 9 Mar 2025 19:14:37 -0300 Subject: [PATCH 161/186] Fix native equal compare --- jParser/base/src/main/java/idl/IDLNativeData.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/jParser/base/src/main/java/idl/IDLNativeData.java b/jParser/base/src/main/java/idl/IDLNativeData.java index d02d0d71..38b24600 100644 --- a/jParser/base/src/main/java/idl/IDLNativeData.java +++ b/jParser/base/src/main/java/idl/IDLNativeData.java @@ -24,7 +24,15 @@ public void reset(IDLBase idlBase, boolean cMemoryOwn) { @Override public boolean equals(Object obj) { - return (obj instanceof IDLBase) && (((IDLNativeData)obj).cPointer == this.cPointer); + if(obj instanceof IDLBase) { + IDLBase idlBase = (IDLBase)obj; + return idlBase.nativeData.cPointer == this.cPointer; + } + else if(obj instanceof IDLNativeData) { + IDLNativeData nativeData = (IDLNativeData)obj; + return nativeData.cPointer == this.cPointer; + } + return false; } @Override From 84e6c06da3d5d2679d19bffb2b490cfba5c1c7c2 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 9 Mar 2025 19:16:49 -0300 Subject: [PATCH 162/186] Remove hashcode override --- jParser/base/src/main/java/idl/IDLNativeData.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/jParser/base/src/main/java/idl/IDLNativeData.java b/jParser/base/src/main/java/idl/IDLNativeData.java index 38b24600..e7d4d9c7 100644 --- a/jParser/base/src/main/java/idl/IDLNativeData.java +++ b/jParser/base/src/main/java/idl/IDLNativeData.java @@ -35,11 +35,6 @@ else if(obj instanceof IDLNativeData) { return false; } - @Override - public int hashCode() { - return (int)cPointer; - } - /** * @return The memory location (pointer) of this instance. */ From 553b3fe3a2e3a534a27ab5a617b7329f36f2210b Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 9 Mar 2025 19:19:59 -0300 Subject: [PATCH 163/186] add IDLBase equals override --- jParser/base/src/main/java/idl/IDLBase.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/jParser/base/src/main/java/idl/IDLBase.java b/jParser/base/src/main/java/idl/IDLBase.java index fa2d847c..80985104 100644 --- a/jParser/base/src/main/java/idl/IDLBase.java +++ b/jParser/base/src/main/java/idl/IDLBase.java @@ -41,4 +41,9 @@ protected void deleteNative() { public static String getJSString(long addr) { return null; } + + @Override + public boolean equals(Object obj) { + return nativeData.equals(obj); + } } \ No newline at end of file From 522a6e9664796d9ce9d356902bcbf27c7d443c65 Mon Sep 17 00:00:00 2001 From: Natan Date: Sun, 9 Mar 2025 21:53:42 -0300 Subject: [PATCH 164/186] Auto set Memory owned to false if its no delete --- .../xpenatan/jparser/idl/parser/IDLConstructorParser.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java index 111b57c2..5832473b 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLConstructorParser.java @@ -128,8 +128,10 @@ public static MethodDeclaration setupConstructor(IDLConstructor idlConstructor, paramData.isStatic = isStatic; IDLMethodParser.setupCallerParam(paramData, caller, parameters, idlConstructor.parameters); + String isMemoryOwned = String.valueOf(!idlConstructor.idlClass.classHeader.isNoDelete); + Statement statement1 = StaticJavaParser.parseStatement("long addr = " + caller + ";"); - Statement statement2 = StaticJavaParser.parseStatement("getNativeData().reset(addr, true);"); + Statement statement2 = StaticJavaParser.parseStatement("getNativeData().reset(addr, " + isMemoryOwned + ");"); blockStmt.addStatement(statement1); blockStmt.addStatement(statement2); From 333e8b89be099ae04dbe0765acb682177895e974 Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 10 Mar 2025 12:08:42 -0300 Subject: [PATCH 165/186] Generate teavm callback --- .../xpenatan/jparser/example/app/TestLib.java | 5 - .../jparser/teavm/TeaVMCodeParser.java | 147 ++++++++++++++++++ 2 files changed, 147 insertions(+), 5 deletions(-) diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java index 751b3db1..d251f068 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/TestLib.java @@ -283,11 +283,6 @@ private static boolean testStaticMethodClass() { private static boolean testCallbackClass() { { - if(Gdx.app.getType() == Application.ApplicationType.WebGL) { - // TODO Not supported yet - return true; - } - TestCallbackClass test = new TestCallbackClass(); try { boolean[] internal_onVoidCallback = { false }; diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index 55fe223b..a25a9a40 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -3,6 +3,7 @@ import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.ImportDeclaration; +import com.github.javaparser.ast.Modifier; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.PackageDeclaration; @@ -12,6 +13,7 @@ import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.body.VariableDeclarator; +import com.github.javaparser.ast.expr.ArrayInitializerExpr; import com.github.javaparser.ast.expr.CastExpr; import com.github.javaparser.ast.expr.ConditionalExpr; import com.github.javaparser.ast.expr.EnclosedExpr; @@ -19,7 +21,12 @@ import com.github.javaparser.ast.expr.MethodCallExpr; import com.github.javaparser.ast.expr.Name; import com.github.javaparser.ast.expr.NormalAnnotationExpr; +import com.github.javaparser.ast.expr.ObjectCreationExpr; import com.github.javaparser.ast.expr.SimpleName; +import com.github.javaparser.ast.expr.StringLiteralExpr; +import com.github.javaparser.ast.expr.VariableDeclarationExpr; +import com.github.javaparser.ast.stmt.BlockStmt; +import com.github.javaparser.ast.stmt.ExpressionStmt; import com.github.javaparser.ast.type.ArrayType; import com.github.javaparser.ast.type.ClassOrInterfaceType; import com.github.javaparser.ast.type.Type; @@ -27,6 +34,7 @@ import com.github.javaparser.resolution.types.ResolvedPrimitiveType; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.utils.Pair; import com.github.xpenatan.jparser.core.JParser; import com.github.xpenatan.jparser.core.JParserHelper; import com.github.xpenatan.jparser.core.JParserItem; @@ -41,6 +49,7 @@ import com.github.xpenatan.jparser.idl.parser.IDLAttributeOperation; import com.github.xpenatan.jparser.idl.parser.IDLDefaultCodeParser; import com.github.xpenatan.jparser.idl.parser.IDLMethodOperation; +import com.github.xpenatan.jparser.idl.parser.IDLMethodParser; import java.io.File; import java.util.ArrayList; import java.util.List; @@ -583,6 +592,144 @@ public void onIDLEnumMethodGenerated(JParser jParser, IDLEnum idlEnum, ClassOrIn } } + @Override + public void onIDLCallbackGenerated(JParser jParser, IDLClass idlClass, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration callbackDeclaration, ArrayList>> methods) { + NodeList methodParameters = callbackDeclaration.getParameters(); + IDLClass idlCallbackClass = idlClass.callbackImpl; + String callbackClassName = idlCallbackClass.name; + Type methodReturnType = callbackDeclaration.getType(); + MethodDeclaration nativeMethodDeclaration = IDLMethodParser.generateNativeMethod(callbackDeclaration.getNameAsString(), methodParameters, methodReturnType, false); + if(!JParserHelper.containsMethod(classDeclaration, nativeMethodDeclaration)) { + NormalAnnotationExpr customAnnotation = new NormalAnnotationExpr(); + customAnnotation.setName("org.teavm.jso.JSBody"); + ArrayInitializerExpr paramsArray = new ArrayInitializerExpr(); + NodeList values = paramsArray.getValues(); + String script = "var " + callbackClassName + " = "+ module + ".wrapPointer(this_addr, " + module + "." + callbackClassName + ");"; + MethodCallExpr caller = IDLMethodParser.createCaller(nativeMethodDeclaration); + + caller.addArgument("getNativeData().getCPointer()"); + + values.add(new StringLiteralExpr("this_addr")); + for(int i = 0; i < methods.size(); i++) { + Pair> pair = methods.get(i); + IDLMethod idlMethod = pair.a; + String methodName = idlMethod.name; + values.add(new StringLiteralExpr(methodName)); + nativeMethodDeclaration.addParameter(methodName, methodName); + script += " " + callbackClassName + "." + methodName + " = " + methodName + ";"; + caller.addArgument(methodName); + } + + customAnnotation.addPair("params", paramsArray); + customAnnotation.addPair("script", new StringLiteralExpr(script)); + nativeMethodDeclaration.addAnnotation(customAnnotation); + classDeclaration.getMembers().add(nativeMethodDeclaration); + + + BlockStmt callbackMethodBody = callbackDeclaration.getBody().get(); + + for(int i = 0; i < methods.size(); i++) { + Pair> pair = methods.get(i); + IDLMethod idlMethod = pair.a; + Pair methodPair = pair.b; + MethodDeclaration internalMethod = methodPair.a; + MethodDeclaration publicMethod = methodPair.b; + String internalMethodName = internalMethod.getNameAsString(); + String paramCode = ""; + String methodName = idlMethod.name; + + Type returnType = internalMethod.getType(); + String returnTypeStr = returnType.asString(); + + NodeList parameters = internalMethod.getParameters(); + createInterfaceClass(classDeclaration, methodName, returnTypeStr, parameters); + createInterfaceInstance(methodName, internalMethodName, returnTypeStr, parameters, callbackMethodBody); + } + callbackMethodBody.addStatement(caller); + } + } + + private void createInterfaceClass(ClassOrInterfaceDeclaration classDeclaration, String methodName, String returnTypeStr, NodeList parameters) { + ClassOrInterfaceDeclaration interfaceDecl = new ClassOrInterfaceDeclaration(); + interfaceDecl.setInterface(true); // Mark it as an interface + interfaceDecl.setName(methodName); + interfaceDecl.setPublic(true); // Optional, interfaces are public by default + interfaceDecl.addExtendedType("org.teavm.jso.JSObject"); + + NormalAnnotationExpr customAnnotation = new NormalAnnotationExpr(); + customAnnotation.setName("org.teavm.jso.JSFunctor"); + interfaceDecl.addAnnotation(customAnnotation); + + MethodDeclaration method = interfaceDecl.addMethod(methodName); + method.removeBody(); + method.setType(returnTypeStr); + for(int i1 = 0; i1 < parameters.size(); i1++) { + Parameter parameter = parameters.get(i1); + Type type = parameter.getType(); + String typeStr = type.asString(); + String paramName = parameter.getNameAsString(); + if(typeStr.equals("String") || JParserHelper.isLong(type)) { + typeStr = "int"; + } + method.addParameter(typeStr, paramName); + } + classDeclaration.addMember(interfaceDecl); + } + + private void createInterfaceInstance(String methodName, String internalMethodName, String returnTypeStr, NodeList parameters, BlockStmt callbackMethodBody) { + ObjectCreationExpr anonymousClass = new ObjectCreationExpr(); + anonymousClass.setType(new ClassOrInterfaceType().setName(methodName)); + + ClassOrInterfaceDeclaration anonymousBody = new ClassOrInterfaceDeclaration(); + anonymousBody.setInterface(false); // This is a class, not an interface + + // Implement onEvent method + MethodDeclaration implMethod1 = anonymousBody.addMethod(methodName, Modifier.Keyword.PUBLIC); + implMethod1.setType(returnTypeStr); + String params = ""; + int paramSize = parameters.size(); + for(int i1 = 0; i1 < paramSize; i1++) { + Parameter parameter = parameters.get(i1); + Type type = parameter.getType(); + String typeStr = type.asString(); + String paramNameOriginal = parameter.getNameAsString(); + String paramName = paramNameOriginal; + + if(typeStr.equals("String")) { + // Edge case where String need to be converted + paramName = "IDLBase.getJSString(" + paramName + ")"; + typeStr = "int"; + } + if(JParserHelper.isLong(type)) { + typeStr = "int"; + } + params += paramName; + if(i1 < paramSize-1) { + params += ", "; + } + implMethod1.addParameter(typeStr, paramNameOriginal); + } + BlockStmt body1 = new BlockStmt(); + String methodCall = internalMethodName + "(" + params + ");"; + String returnCode = ""; + if(!returnTypeStr.equals("void")) { + returnCode = "return "; + } + body1.addStatement(returnCode + methodCall); + implMethod1.setBody(body1); + + anonymousClass.setAnonymousClassBody(anonymousBody.getMembers()); + + VariableDeclarationExpr varDecl = new VariableDeclarationExpr( + new VariableDeclarator( + new ClassOrInterfaceType().setName(methodName), + methodName, + anonymousClass + ) + ); + callbackMethodBody.addStatement(new ExpressionStmt(varDecl)); + } + @Override public void onParserComplete(JParser jParser, ArrayList parserItems) { super.onParserComplete(jParser, parserItems); From 188e7f02c32f4752057a3e3911e6d57cb54d0b16 Mon Sep 17 00:00:00 2001 From: Natan Date: Mon, 10 Mar 2025 21:45:02 -0300 Subject: [PATCH 166/186] Add emscripten stack size and option to change it --- .../xpenatan/jparser/builder/targets/EmscriptenTarget.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java index b677145b..ad57b2d1 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/EmscriptenTarget.java @@ -22,6 +22,9 @@ public class EmscriptenTarget extends DefaultBuildTarget { String WEBIDL_BINDER_SCRIPT = EMSCRIPTEN_ROOT + "tools/webidl_binder.py"; + public long initialMemory = 64 * 1024 * 1024; + public long stackSize = 1048576; + public EmscriptenTarget() { this(null); } @@ -98,7 +101,6 @@ protected boolean build(BuildConfig config, CustomFileDescriptor buildTargetTemp } else { String postPath = createPostJS(jsglueDir, libName); - long initialMemory = 64 * 1024 * 1024; linkerFlags.add("--llvm-lto"); linkerFlags.add("1"); linkerFlags.add("-s"); @@ -112,6 +114,8 @@ protected boolean build(BuildConfig config, CustomFileDescriptor buildTargetTemp linkerFlags.add("-s"); linkerFlags.add("INITIAL_MEMORY=" + initialMemory); linkerFlags.add("-s"); + linkerFlags.add("STACK_SIZE=" + stackSize); + linkerFlags.add("-s"); linkerFlags.add("EXPORTED_FUNCTIONS=['_free','_malloc']"); linkerFlags.add("-s"); linkerFlags.add("EXPORTED_RUNTIME_METHODS=['UTF8ToString']"); From c097787c4c4870f28ea33fbc1b5005c0b9031f45 Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 12 Mar 2025 21:43:57 -0300 Subject: [PATCH 167/186] Attempt to fix cpp subpackage. Also print mapping. --- .../com/github/xpenatan/jparser/core/JParser.java | 7 +++---- .../com/github/xpenatan/jparser/core/JParserItem.java | 6 ++---- .../jparser/idl/parser/IDLClassGeneratorParser.java | 11 +++++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParser.java b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParser.java index 1d8773c8..45c71e3f 100644 --- a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParser.java +++ b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParser.java @@ -176,13 +176,11 @@ else if(path.contains(exclude)) { continue; } String javaContent = file.readString(); - File file1 = file.file(); CompilationUnit unit = StaticJavaParser.parse(new ByteArrayInputStream(javaContent.getBytes())); unit.printer(new CustomPrettyPrinter()); - String absolutePath = file1.getAbsolutePath(); String genPath = fileGenDir.file().getAbsolutePath(); - jParser.unitArray.add(new JParserItem(unit, absolutePath, genPath)); + jParser.unitArray.add(new JParserItem(unit, genPath)); } } } @@ -194,7 +192,8 @@ private static void generateFile(String destinationPath, String javaContent) { } private static String getFullyQualifiedClassName(CustomFileDescriptor fileSourceDir, CustomFileDescriptor file) { - String className = file.path().replace(fileSourceDir.path(), "").replace('\\', '.').replace('/', '.').replace(".java", ""); + String replacePath = file.path().replace(fileSourceDir.path(), "").replace("\\", "/"); + String className = replacePath.replace("/", ".").replace('/', '.').replace(".java", ""); if(className.startsWith(".")) className = className.substring(1); return className; } diff --git a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParserItem.java b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParserItem.java index 939a2698..ee8721a6 100644 --- a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParserItem.java +++ b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/JParserItem.java @@ -15,16 +15,14 @@ */ public class JParserItem { public CompilationUnit unit; - public String inputPath; public final String destinationBaseDir; public String packagePathName; public String className = ""; public boolean notAllowed; public boolean isIDL; - public JParserItem(CompilationUnit unit, String inputPath, String destinationBaseDir) { + public JParserItem(CompilationUnit unit, String destinationBaseDir) { this.unit = unit; - this.inputPath = inputPath; this.destinationBaseDir = destinationBaseDir; List allEnum = unit.findAll(EnumDeclaration.class); List all = unit.findAll(ClassOrInterfaceDeclaration.class); @@ -32,7 +30,7 @@ public JParserItem(CompilationUnit unit, String inputPath, String destinationBas if(all.size() > 0) { className = all.get(0).getNameAsString(); String packageName = unit.getPackageDeclaration().get().getNameAsString(); - this.packagePathName = packageName.replace(".", File.separator); + this.packagePathName = packageName.replace(".", "/"); } //TODO support enum // else if(allEnum.size() > 0) { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java index eb941446..6c635bee 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java @@ -106,7 +106,7 @@ private void createBaseUnitFromResources(JParser jParser) { } String newPackage = basePackage + originalPackage; compilationUnit.setPackageDeclaration(newPackage); - JParserItem jParserItem = new JParserItem(compilationUnit, jParser.genDir, jParser.genDir); + JParserItem jParserItem = new JParserItem(compilationUnit, jParser.genDir); if(!JParser.CREATE_IDL_HELPER) { jParserItem.notAllowed = true; } @@ -124,6 +124,9 @@ private void createBaseUnitFromResources(JParser jParser) { } private void generateIDLJavaClasses(JParser jParser, String genPath) { + System.out.println("Class Mapping: "); + System.out.println(classCppPath); + for(IDLFile idlFile : idlReader.fileArray) { for(IDLClassOrEnum idlClassOrEnum : idlFile.classArray) { String className = idlClassOrEnum.name; @@ -143,12 +146,12 @@ private void generateIDLJavaClasses(JParser jParser, String genPath) { Path p = Paths.get(includeClass); Path parent = p.getParent(); if(parent != null) { - String string = parent.toString(); - subPackage = string.replace(File.separator, ".").toLowerCase(); + String string = parent.toString().replace("\\", "/"); + subPackage = string.replace("/", ".").toLowerCase(); } } CompilationUnit compilationUnit = setupClass(idlClassOrEnum, subPackage); - parserItem = new JParserItem(compilationUnit, genPath, genPath); + parserItem = new JParserItem(compilationUnit, genPath); jParser.unitArray.add(parserItem); } } From 4004b4788d1b6e0f9219917c12c6e1d5826b8bf2 Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 12 Mar 2025 22:14:15 -0300 Subject: [PATCH 168/186] More logging --- .../com/github/xpenatan/jparser/core/util/FileHelper.java | 7 +++++-- .../jparser/idl/parser/IDLClassGeneratorParser.java | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/util/FileHelper.java b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/util/FileHelper.java index 39185a6d..66989bdd 100644 --- a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/util/FileHelper.java +++ b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/util/FileHelper.java @@ -78,8 +78,11 @@ public static ArrayList getFilesFromDir(String src) { public static ArrayList copyDir(Path src) throws IOException { ArrayList outPath = new ArrayList<>(); - String srcFullPath = src.toFile().getCanonicalPath(); - if(Files.exists(src)) { + String srcFullPath = src.toFile().getCanonicalPath().replace("\\", "/"); + boolean exists = Files.exists(src); + System.out.println("CopyDir: "); + System.out.println(exists + " " + srcFullPath); + if(exists) { Files.walkFileTree(src, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException { diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java index 6c635bee..756b2ead 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java @@ -160,8 +160,10 @@ private void generateIDLJavaClasses(JParser jParser, String genPath) { private HashMap getClassCppPath() { HashMap mapPackage = new HashMap<>(); + System.out.println("includeDir: " + includeDir); if(includeDir != null) { ArrayList filesFromDir = FileHelper.getFilesFromDir(includeDir); + System.out.println("filesFromDir: " + filesFromDir.size()); for(String path : filesFromDir) { if(!path.endsWith(".h")) continue; From 3925600ca20404eb4ac77abb79b456314b49c125 Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 12 Mar 2025 22:19:26 -0300 Subject: [PATCH 169/186] More logging --- .../github/xpenatan/jparser/core/util/FileHelper.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/util/FileHelper.java b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/util/FileHelper.java index 66989bdd..0bf98606 100644 --- a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/util/FileHelper.java +++ b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/util/FileHelper.java @@ -68,7 +68,8 @@ public FileVisitResult postVisitDirectory(Path directory, IOException ioExceptio } public static ArrayList getFilesFromDir(String src) { - Path srcPath = new File(src).toPath(); + src = src.replace("\\", "/"); + Path srcPath = Path.of(src); try { return copyDir(srcPath); } catch(IOException e) { @@ -86,10 +87,8 @@ public static ArrayList copyDir(Path src) throws IOException { Files.walkFileTree(src, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException { - File file = path.toFile(); - String fullPath = file.getCanonicalPath(); - String name = fullPath.replace(srcFullPath, ""); - outPath.add(file.getCanonicalPath()); + String fullPath = path.toFile().getCanonicalPath().replace("\\", "/"); + outPath.add(fullPath); return FileVisitResult.CONTINUE; } From 3a24b43a8930d83981a8530efb8841b0f7212ef4 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 13 Mar 2025 13:36:27 -0300 Subject: [PATCH 170/186] Experimental -static-libgcc --- .../github/xpenatan/jparser/builder/targets/LinuxTarget.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/LinuxTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/LinuxTarget.java index 904a8d47..268d4910 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/LinuxTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/LinuxTarget.java @@ -30,6 +30,7 @@ public LinuxTarget() { cppFlags.add("-Wno-unused-but-set-variable"); cppFlags.add("-w"); cppFlags.add("-Wno-format"); +// -static-libgcc } @Override @@ -45,6 +46,7 @@ protected void setup(BuildConfig config) { // Linux have an issue with libstdc++, libgcc and libc where if the system uses an updated version when compiling, older linux version will fail to run. // static linking may fix libstdc++ and libgcc but not libc because it's not possible to static link it. linkerFlags.add("-shared"); + linkerFlags.add("-static-libgcc"); linkerFlags.add("-m64"); libSuffix = "64.so"; } From 8357705d2b9ea002eaff97877bff3a99163cc8e9 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 13 Mar 2025 14:27:03 -0300 Subject: [PATCH 171/186] Revert --- .../com/github/xpenatan/jparser/builder/targets/LinuxTarget.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/LinuxTarget.java b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/LinuxTarget.java index 268d4910..c6877610 100644 --- a/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/LinuxTarget.java +++ b/jParser/builder/src/main/java/com/github/xpenatan/jparser/builder/targets/LinuxTarget.java @@ -46,7 +46,6 @@ protected void setup(BuildConfig config) { // Linux have an issue with libstdc++, libgcc and libc where if the system uses an updated version when compiling, older linux version will fail to run. // static linking may fix libstdc++ and libgcc but not libc because it's not possible to static link it. linkerFlags.add("-shared"); - linkerFlags.add("-static-libgcc"); linkerFlags.add("-m64"); libSuffix = "64.so"; } From 71dcb5696d3bf46f481f34a4000693051fc14ed7 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 13 Mar 2025 15:01:11 -0300 Subject: [PATCH 172/186] Print load exception --- .../com/github/xpenatan/jparser/loader/JParserLibraryLoader.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java b/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java index 0932a88f..7d55ff47 100644 --- a/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java +++ b/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java @@ -30,6 +30,7 @@ public void loadInternal(String libraryName, JParserLibraryLoaderListener listen listener.onLoad(true); } catch(Exception e) { + e.printStackTrace(); listener.onLoad(false); } }).start(); From 24a6c4721e1ba05f0c48eae400d268ca0808499a Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 13 Mar 2025 15:39:34 -0300 Subject: [PATCH 173/186] Change loader logic --- .../xpenatan/jparser/example/app/AppTest.java | 7 +------ .../example/testlib/TestLibLoader.java | 20 +++++++++---------- example/lib/lib-core/build.gradle.kts | 5 +++-- .../jparser/loader/JParserLibraryLoader.java | 4 ++-- .../loader/JParserLibraryLoaderListener.java | 2 +- .../jparser/loader/JParserLibraryLoader.java | 5 +++-- 6 files changed, 20 insertions(+), 23 deletions(-) diff --git a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java index 6b2f6121..3a135fd0 100644 --- a/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java +++ b/example/app/core/src/main/java/com/github/xpenatan/jparser/example/app/AppTest.java @@ -20,12 +20,7 @@ public class AppTest extends ApplicationAdapter { @Override public void create() { - TestLibLoader.init(new Runnable() { - @Override - public void run() { - init = true; - } - }); + TestLibLoader.init((isSuccess, e) -> init = isSuccess); batch = new SpriteBatch(); font = new BitmapFont(); diff --git a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/TestLibLoader.java b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/TestLibLoader.java index 6f6c115e..68c7f4db 100644 --- a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/TestLibLoader.java +++ b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/TestLibLoader.java @@ -1,6 +1,7 @@ package com.github.xpenatan.jparser.example.testlib; import com.github.xpenatan.jparser.loader.JParserLibraryLoader; +import com.github.xpenatan.jparser.loader.JParserLibraryLoaderListener; public class TestLibLoader { @@ -18,21 +19,20 @@ public interface OnInitFunction extends org.teavm.jso.JSObject { */ /*[-TEAVM;-REPLACE] - public static void init(Runnable onSuccess) { + public static void init(JParserLibraryLoaderListener listener) { JParserLibraryLoader libraryLoader = new JParserLibraryLoader(); - OnInitFunction onInitFunction = () -> onSuccess.run(); - setOnLoadInit(onInitFunction); - libraryLoader.load(LIB_NAME + ".wasm", isSuccess -> {}); + setOnLoadInit(() -> listener.onLoad(true, null)); + libraryLoader.load(LIB_NAME + ".wasm", (isSuccess, e) -> { + if(!isSuccess) { + listener.onLoad(false, e); + } + }); } */ - public static void init(Runnable onSuccess) { + public static void init(JParserLibraryLoaderListener listener) { JParserLibraryLoader libraryLoader = new JParserLibraryLoader(); - libraryLoader.load(LIB_NAME, isSuccess -> { - if(isSuccess) { - onSuccess.run(); - } - }); + libraryLoader.load(LIB_NAME, listener); } /*[-TEAVM;-REPLACE] diff --git a/example/lib/lib-core/build.gradle.kts b/example/lib/lib-core/build.gradle.kts index eba178a5..43b6ae4f 100644 --- a/example/lib/lib-core/build.gradle.kts +++ b/example/lib/lib-core/build.gradle.kts @@ -1,13 +1,14 @@ plugins { id("java") + id("java-library") } dependencies { if(LibExt.exampleUseRepoLibs) { - implementation("com.github.xpenatan.jParser:loader-core:${LibExt.libVersion}") + api("com.github.xpenatan.jParser:loader-core:${LibExt.libVersion}") } else { - implementation(project(":jParser:loader:loader-core")) + api(project(":jParser:loader:loader-core")) } } diff --git a/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java b/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java index 7d55ff47..fd0768f2 100644 --- a/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java +++ b/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java @@ -27,11 +27,11 @@ public void loadInternal(String libraryName, JParserLibraryLoaderListener listen new Thread(() -> { try { loader.load(libraryName); - listener.onLoad(true); + listener.onLoad(true, null); } catch(Exception e) { e.printStackTrace(); - listener.onLoad(false); + listener.onLoad(false, e); } }).start(); } diff --git a/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoaderListener.java b/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoaderListener.java index fc48f4b7..378cfa7d 100644 --- a/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoaderListener.java +++ b/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoaderListener.java @@ -1,5 +1,5 @@ package com.github.xpenatan.jparser.loader; public interface JParserLibraryLoaderListener { - void onLoad(boolean isSuccess); + void onLoad(boolean isSuccess, Exception e); } \ No newline at end of file diff --git a/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java b/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java index e672a512..68f638bf 100644 --- a/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java +++ b/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java @@ -5,6 +5,7 @@ import com.github.xpenatan.gdx.backends.teavm.assetloader.AssetLoaderListener; import com.github.xpenatan.jparser.loader.JParserLibraryLoaderListener; import java.util.HashSet; +import javax.script.ScriptException; public class JParserLibraryLoader { @@ -35,11 +36,11 @@ public void loadInternal(String libraryName, JParserLibraryLoaderListener listen instance.loadScript(libraryName, new AssetLoaderListener<>(){ @Override public void onSuccess(String url, String result) { - listener.onLoad(true); + listener.onLoad(true, null); } @Override public void onFailure(String url) { - listener.onLoad(false); + listener.onLoad(false, new ScriptException("Failed to load script: " + url)); } }); } From 3f46f88227c6a537c00390bd8aa7f788dfd184e3 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 13 Mar 2025 16:55:14 -0300 Subject: [PATCH 174/186] Update JParserLibraryLoader to make it easier to load scripts --- .../example/testlib/TestLibLoader.java | 29 +------ .../jparser/loader/JParserLibraryLoader.java | 44 ++++------- jParser/loader/loader-teavm/build.gradle.kts | 1 + .../jparser/loader/JParserLibraryLoader.java | 76 +++++++++++++------ 4 files changed, 69 insertions(+), 81 deletions(-) diff --git a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/TestLibLoader.java b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/TestLibLoader.java index 68c7f4db..b7e71b29 100644 --- a/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/TestLibLoader.java +++ b/example/lib/lib-base/src/main/java/com/github/xpenatan/jparser/example/testlib/TestLibLoader.java @@ -11,34 +11,7 @@ public class TestLibLoader { #include "CustomCode.h" */ - /*[-TEAVM;-ADD] - @org.teavm.jso.JSFunctor - public interface OnInitFunction extends org.teavm.jso.JSObject { - void onInit(); - } - */ - - /*[-TEAVM;-REPLACE] - public static void init(JParserLibraryLoaderListener listener) { - JParserLibraryLoader libraryLoader = new JParserLibraryLoader(); - setOnLoadInit(() -> listener.onLoad(true, null)); - libraryLoader.load(LIB_NAME + ".wasm", (isSuccess, e) -> { - if(!isSuccess) { - listener.onLoad(false, e); - } - }); - } - */ - public static void init(JParserLibraryLoaderListener listener) { - JParserLibraryLoader libraryLoader = new JParserLibraryLoader(); - libraryLoader.load(LIB_NAME, listener); + JParserLibraryLoader.load(LIB_NAME, listener); } - - /*[-TEAVM;-REPLACE] - @org.teavm.jso.JSBody(params = { "onInitFunction" }, script = "window.TestLibOnInit = onInitFunction;") - private static native void setOnLoadInit(OnInitFunction onInitFunction); - */ - /*[-JNI;-REMOVE] */ - public static native void setOnLoadInit(); } \ No newline at end of file diff --git a/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java b/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java index fd0768f2..574033b3 100644 --- a/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java +++ b/jParser/loader/loader-core/src/main/java/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java @@ -4,39 +4,27 @@ public class JParserLibraryLoader { - private final SharedLibraryLoader loader; + private static final SharedLibraryLoader loader = new SharedLibraryLoader(); - public JParserLibraryLoader() { - loader = new SharedLibraryLoader(); - } - - public JParserLibraryLoader(String nativesJar) { - loader = new SharedLibraryLoader(nativesJar); - } + private JParserLibraryLoader() {} - public void load(String libraryName) { - loadInternal(libraryName, null); - } - - public void load(String libraryName, JParserLibraryLoaderListener listener) { + public static void load(String libraryName, JParserLibraryLoaderListener listener) { loadInternal(libraryName, listener); } - public void loadInternal(String libraryName, JParserLibraryLoaderListener listener) { - if(listener != null) { - new Thread(() -> { - try { - loader.load(libraryName); - listener.onLoad(true, null); - } - catch(Exception e) { - e.printStackTrace(); - listener.onLoad(false, e); - } - }).start(); - } - else { - loader.load(libraryName); + private static void loadInternal(String libraryName, JParserLibraryLoaderListener listener) { + if(listener == null) { + throw new RuntimeException("Should implement listener"); } + new Thread(() -> { + try { + loader.load(libraryName); + listener.onLoad(true, null); + } + catch(Exception e) { + e.printStackTrace(); + listener.onLoad(false, e); + } + }).start(); } } diff --git a/jParser/loader/loader-teavm/build.gradle.kts b/jParser/loader/loader-teavm/build.gradle.kts index ece835f9..6c7c5734 100644 --- a/jParser/loader/loader-teavm/build.gradle.kts +++ b/jParser/loader/loader-teavm/build.gradle.kts @@ -6,6 +6,7 @@ val moduleName = "loader-teavm" dependencies { implementation(project(":jParser:loader:loader-core")) + implementation("org.teavm:teavm-jso:${LibExt.teaVMVersion}") implementation("com.github.xpenatan.gdx-teavm:asset-loader:${LibExt.gdxTeaVMVersion}") } diff --git a/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java b/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java index 68f638bf..2f999ec1 100644 --- a/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java +++ b/jParser/loader/loader-teavm/src/main/java/emu/com/github/xpenatan/jparser/loader/JParserLibraryLoader.java @@ -6,46 +6,72 @@ import com.github.xpenatan.jparser.loader.JParserLibraryLoaderListener; import java.util.HashSet; import javax.script.ScriptException; +import org.teavm.jso.JSBody; +import org.teavm.jso.JSFunctor; public class JParserLibraryLoader { private static HashSet loadedLibraries = new HashSet<>(); - public JParserLibraryLoader() { - } - - public void load(String libraryName) { - loadInternal(libraryName, null); - } + private JParserLibraryLoader() {} - public void load(String libraryName, JParserLibraryLoaderListener listener) { + public static void load(String libraryName, JParserLibraryLoaderListener listener) { loadInternal(libraryName, listener); } - public void loadInternal(String libraryName, JParserLibraryLoaderListener listener) { - if(!libraryName.endsWith(".js")) { - libraryName = libraryName + ".js"; + private static void loadInternal(final String libraryName, JParserLibraryLoaderListener listener) { + if(listener == null) { + throw new RuntimeException("Should implement listener"); } if(loadedLibraries.contains(libraryName)) { return; } - loadedLibraries.add(libraryName); + + // Try to load wasm first + loadWasm(libraryName, listener); + } + + private static void loadWasm(final String libraryName, JParserLibraryLoaderListener listener) { AssetLoader instance = AssetInstance.getLoaderInstance(); - if(listener != null) { - instance.loadScript(libraryName, new AssetLoaderListener<>(){ - @Override - public void onSuccess(String url, String result) { + instance.loadScript(libraryName + ".wasm.js", new AssetLoaderListener<>() { + @Override + public void onSuccess(String url, String result) { + // Wasm requires to setup wasm first + String fullLibName = libraryName + "OnInit"; + setOnLoadInit(fullLibName, () -> { + loadedLibraries.add(libraryName); listener.onLoad(true, null); - } - @Override - public void onFailure(String url) { - listener.onLoad(false, new ScriptException("Failed to load script: " + url)); - } - }); - } - else { - instance.loadScript(libraryName); - } + }); + } + @Override + public void onFailure(String url) { + // Fallback to javascript + loadJS(libraryName, listener); + } + }); + } + + private static void loadJS(final String libraryName, JParserLibraryLoaderListener listener) { + AssetLoader instance = AssetInstance.getLoaderInstance(); + instance.loadScript(libraryName + ".js", new AssetLoaderListener<>() { + @Override + public void onSuccess(String url, String result) { + loadedLibraries.add(libraryName); + listener.onLoad(true, null); + } + @Override + public void onFailure(String url) { + listener.onLoad(false, new ScriptException("Failed to load script: " + url)); + } + }); } + + @JSFunctor + public interface OnInitFunction extends org.teavm.jso.JSObject { + void onInit(); + } + + @JSBody(params = { "libraryName", "onInitFunction" }, script = "window[libraryName] = onInitFunction;") + private static native void setOnLoadInit(String libraryName, OnInitFunction onInitFunction); } \ No newline at end of file From 74718fd9457d36fd6d60e6258108c622e5167fd2 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 13 Mar 2025 19:26:07 -0300 Subject: [PATCH 175/186] Remove space --- jParser/base/src/main/java/idl/IDLNativeData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jParser/base/src/main/java/idl/IDLNativeData.java b/jParser/base/src/main/java/idl/IDLNativeData.java index e7d4d9c7..d55a088f 100644 --- a/jParser/base/src/main/java/idl/IDLNativeData.java +++ b/jParser/base/src/main/java/idl/IDLNativeData.java @@ -98,7 +98,7 @@ public String toString() { @Override protected void finalize() throws Throwable { if(cMemOwn && !disposed && IDLBase.ENABLE_LOGGING) { - error("IDL", " Memory Leak - " + idlBase.getClass().getSimpleName() + " was not disposed correctly."); + error("IDL", "Memory Leak - " + idlBase.getClass().getSimpleName() + " was not disposed correctly."); } super.finalize(); } From 22d42343a1823ea8266ceaadf7af8b8c8bf05824 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 13 Mar 2025 19:37:12 -0300 Subject: [PATCH 176/186] Remove some logs --- .../java/com/github/xpenatan/jparser/core/util/FileHelper.java | 3 --- .../xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/util/FileHelper.java b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/util/FileHelper.java index 0bf98606..2936fe3c 100644 --- a/jParser/core/src/main/java/com/github/xpenatan/jparser/core/util/FileHelper.java +++ b/jParser/core/src/main/java/com/github/xpenatan/jparser/core/util/FileHelper.java @@ -79,10 +79,7 @@ public static ArrayList getFilesFromDir(String src) { public static ArrayList copyDir(Path src) throws IOException { ArrayList outPath = new ArrayList<>(); - String srcFullPath = src.toFile().getCanonicalPath().replace("\\", "/"); boolean exists = Files.exists(src); - System.out.println("CopyDir: "); - System.out.println(exists + " " + srcFullPath); if(exists) { Files.walkFileTree(src, new SimpleFileVisitor() { @Override diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java index 756b2ead..ac782239 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java @@ -163,7 +163,7 @@ private HashMap getClassCppPath() { System.out.println("includeDir: " + includeDir); if(includeDir != null) { ArrayList filesFromDir = FileHelper.getFilesFromDir(includeDir); - System.out.println("filesFromDir: " + filesFromDir.size()); + System.out.println("FilesFromDir: " + filesFromDir.size()); for(String path : filesFromDir) { if(!path.endsWith(".h")) continue; From 64cfdc4252aec2f04782aeada502d5d732227cca Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 13 Mar 2025 19:47:25 -0300 Subject: [PATCH 177/186] Add package renaming support --- .../github/xpenatan/jparser/idl/IDLPackageRenaming.java | 5 +++++ .../jparser/idl/parser/IDLClassGeneratorParser.java | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLPackageRenaming.java diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLPackageRenaming.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLPackageRenaming.java new file mode 100644 index 00000000..7d2b05d7 --- /dev/null +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLPackageRenaming.java @@ -0,0 +1,5 @@ +package com.github.xpenatan.jparser.idl; + +public interface IDLPackageRenaming { + String obtainNewPackage(String classPackage); +} \ No newline at end of file diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java index ac782239..48f92108 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java @@ -33,8 +33,8 @@ import com.github.xpenatan.jparser.idl.IDLFile; import com.github.xpenatan.jparser.idl.IDLReader; import com.github.xpenatan.jparser.core.util.ResourceList; +import com.github.xpenatan.jparser.idl.IDLPackageRenaming; import idl.IDLBase; -import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; @@ -65,6 +65,8 @@ public abstract class IDLClassGeneratorParser extends DefaultCodeParser { protected String includeDir; + public IDLPackageRenaming packageRenaming; + /** * @param basePackage Base module source. This is used to generate other sources * @param headerCMD This is the first command option that this parser will use. Ex teavm, C++. @@ -78,7 +80,6 @@ public IDLClassGeneratorParser(String basePackage, String headerCMD, IDLReader i this.idlReader = idlReader; if(this.includeDir != null) { this.includeDir = this.includeDir.replace("\\", "/").replace("//", "/"); - ; } } @@ -148,6 +149,9 @@ private void generateIDLJavaClasses(JParser jParser, String genPath) { if(parent != null) { String string = parent.toString().replace("\\", "/"); subPackage = string.replace("/", ".").toLowerCase(); + if(packageRenaming != null) { + subPackage = packageRenaming.obtainNewPackage(subPackage); + } } } CompilationUnit compilationUnit = setupClass(idlClassOrEnum, subPackage); From a1ca2e0a07b1a8c4cbb159ce51aa96dd87345000 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 13 Mar 2025 19:50:19 -0300 Subject: [PATCH 178/186] Add renaming support --- .../xpenatan/jparser/builder/tool/BuilderTool.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/jParser/builder-tool/src/main/java/com/github/xpenatan/jparser/builder/tool/BuilderTool.java b/jParser/builder-tool/src/main/java/com/github/xpenatan/jparser/builder/tool/BuilderTool.java index 3aa1e642..ae1c32a5 100644 --- a/jParser/builder-tool/src/main/java/com/github/xpenatan/jparser/builder/tool/BuilderTool.java +++ b/jParser/builder-tool/src/main/java/com/github/xpenatan/jparser/builder/tool/BuilderTool.java @@ -7,6 +7,7 @@ import com.github.xpenatan.jparser.cpp.CppCodeParser; import com.github.xpenatan.jparser.cpp.CppGenerator; import com.github.xpenatan.jparser.cpp.NativeCPPGenerator; +import com.github.xpenatan.jparser.idl.IDLPackageRenaming; import com.github.xpenatan.jparser.idl.IDLReader; import com.github.xpenatan.jparser.teavm.TeaVMCodeParser; import java.util.ArrayList; @@ -14,14 +15,18 @@ public class BuilderTool { public static void build(BuildToolOptions op, BuildToolListener listener) { + build(op, listener, null); + } + + public static void build(BuildToolOptions op, BuildToolListener listener, IDLPackageRenaming packageRenaming) { try { - generateAndBuild(op, listener); + generateAndBuild(op, listener, packageRenaming); } catch(Exception e) { throw new RuntimeException(e); } } - private static void generateAndBuild(BuildToolOptions op, BuildToolListener listener) throws Exception { + private static void generateAndBuild(BuildToolOptions op, BuildToolListener listener, IDLPackageRenaming packageRenaming) throws Exception { op.setup(); IDLReader idlReader = IDLReader.readIDL(op.getIDLPath()); @@ -31,12 +36,14 @@ private static void generateAndBuild(BuildToolOptions op, BuildToolListener list CppGenerator cppGenerator = new NativeCPPGenerator(op.getCPPDestinationPath()); CppCodeParser cppParser = new CppCodeParser(cppGenerator, idlReader, op.libBasePackage, op.getSourceDir()); cppParser.generateClass = true; + cppParser.packageRenaming = packageRenaming; JParser.generate(cppParser, op.getModuleBaseJavaDir(), op.getModuleCorePath() + "/src/main/java"); } if(op.generateTeaVM) { // EmscriptenTarget.SKIP_GLUE_CODE = true; TeaVMCodeParser teavmParser = new TeaVMCodeParser(idlReader, op.moduleName, op.libBasePackage, op.getSourceDir()); + teavmParser.packageRenaming = packageRenaming; JParser.generate(teavmParser, op.getModuleBaseJavaDir(), op.getModuleTeaVMPath() + "/src/main/java/"); } From 9fb4bc13614d2b27bc02b9f1948944eefa680e36 Mon Sep 17 00:00:00 2001 From: Natan Date: Thu, 13 Mar 2025 19:52:13 -0300 Subject: [PATCH 179/186] Pass class name also --- .../com/github/xpenatan/jparser/idl/IDLPackageRenaming.java | 2 +- .../jparser/idl/parser/IDLClassGeneratorParser.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLPackageRenaming.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLPackageRenaming.java index 7d2b05d7..7a6eeda2 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLPackageRenaming.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/IDLPackageRenaming.java @@ -1,5 +1,5 @@ package com.github.xpenatan.jparser.idl; public interface IDLPackageRenaming { - String obtainNewPackage(String classPackage); + String obtainNewPackage(String className, String classPackage); } \ No newline at end of file diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java index 48f92108..ce65d9fa 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLClassGeneratorParser.java @@ -149,11 +149,11 @@ private void generateIDLJavaClasses(JParser jParser, String genPath) { if(parent != null) { String string = parent.toString().replace("\\", "/"); subPackage = string.replace("/", ".").toLowerCase(); - if(packageRenaming != null) { - subPackage = packageRenaming.obtainNewPackage(subPackage); - } } } + if(packageRenaming != null) { + subPackage = packageRenaming.obtainNewPackage(className, subPackage); + } CompilationUnit compilationUnit = setupClass(idlClassOrEnum, subPackage); parserItem = new JParserItem(compilationUnit, genPath); jParser.unitArray.add(parserItem); From 0911030ad7b43d88ba82570967b7c18ed4cd3a31 Mon Sep 17 00:00:00 2001 From: Natan Date: Fri, 14 Mar 2025 07:33:46 -0300 Subject: [PATCH 180/186] Improve idl generator to be able to add more webidls --- ...all].run.xml => build_project_all.run.xml} | 2 +- .run/build_project_teavm.run.xml | 24 +++++++++++++++++++ .run/build_project_windows64.run.xml | 24 +++++++++++++++++++ .run/clean.run.xml | 24 +++++++++++++++++++ .run/generate_project.run.xml | 24 +++++++++++++++++++ ...sktop].run.xml => run-app-desktop.run.xml} | 2 +- ...p-teavm].run.xml => run-app-teavm.run.xml} | 2 +- .../jparser/builder/tool/BuilderTool.java | 8 +++---- .../xpenatan/jparser/idl/IDLReader.java | 21 ++++++++-------- 9 files changed, 113 insertions(+), 18 deletions(-) rename .run/{jParser_example_lib_lib-build [build_project_all].run.xml => build_project_all.run.xml} (84%) create mode 100644 .run/build_project_teavm.run.xml create mode 100644 .run/build_project_windows64.run.xml create mode 100644 .run/clean.run.xml create mode 100644 .run/generate_project.run.xml rename .run/{jParser_example_app_desktop [run-app-desktop].run.xml => run-app-desktop.run.xml} (84%) rename .run/{jParser_example_app_teavm [run-app-teavm].run.xml => run-app-teavm.run.xml} (85%) diff --git a/.run/jParser_example_lib_lib-build [build_project_all].run.xml b/.run/build_project_all.run.xml similarity index 84% rename from .run/jParser_example_lib_lib-build [build_project_all].run.xml rename to .run/build_project_all.run.xml index ed10b5e4..4571da5f 100644 --- a/.run/jParser_example_lib_lib-build [build_project_all].run.xml +++ b/.run/build_project_all.run.xml @@ -1,5 +1,5 @@ - +