From 6e397e588ee19aed8e796dcfb6afc50080893106 Mon Sep 17 00:00:00 2001 From: Demetrius Kanios Date: Wed, 16 Sep 2026 22:06:45 -0700 Subject: [PATCH] README and example --- README.md | 86 +++++++++++++++++++++++++++++++++++++ example/.gitignore | 18 ++++++++ example/dub.json | 21 +++++++++ example/dub.selections.json | 6 +++ example/source/app.d | 35 +++++++++++++++ 5 files changed, 166 insertions(+) create mode 100644 README.md create mode 100644 example/.gitignore create mode 100644 example/dub.json create mode 100644 example/dub.selections.json create mode 100644 example/source/app.d diff --git a/README.md b/README.md new file mode 100644 index 0000000..baafa29 --- /dev/null +++ b/README.md @@ -0,0 +1,86 @@ +# Pumpkin API for D + +This package privdes D bindings for building Pumpkin plugins using WebAssembly (Wasm) components. + +You will need [LDC](https://github.com/ldc-developers/ldc) 1.43 or later as the compiler, with the `addon-wasi` package installed. + +## Quick Start + +1. Setup Your DUB Project + +Create a `dub.json` configuration file for your plugin: + +```json +{ + "name": "pumpkin-plugin-example", + "description": "A minimal Pumpkin plugin built with D.", + "license": "proprietary", + "authors": ["You"], + "copyright": "Copyright © 2026, You", + + "dependencies": { "pumpkin-api-d": "~>0.1.0" }, + + "targetType": "executable", + "dflags": ["-Xcc=-mexec-model=reactor"], + "buildTypes": { + "debug": { + "buildOptions": ["debugMode", "debugInfo"] + }, + "release": { + "buildOptions": ["optimize", "inline"], + "dflags": ["-L-S"] + } + } +} +``` + +2. Write Your Plugin + +Create your source file in (e.g. `source/plugin.d`) + +```d +module plugin; + +import wit.pumpkin.plugin.plugin; +import wit.common; +import pumpkin.register; + +struct MyPlugin { + @GetMetadata PluginMetadata getMetadata() + { + immutable(WitString)[$] authors = [ + "You".witList + ]; + + return (immutable PluginMetadata( + name: "pumpkin-plugin-example".witList, + version_: "0.1.0".witList, + authors: authors.witList, + description: "An example plugin in D.".witList, + dependencies: WitList!WitString(), + permissions: WitList!WitString() + )).witClone; + } + + @OnLoad + Result!(void, WitString) onLoad(Context ctx) + { + scope(exit) ctx.witDrop; // incoming resources need to be cleaned up after they are done being used + + log(Level.info, "Hello from D!".witList); + return ok!WitString; + } +} + +mixin RegisterPlugin!MyPlugin; +``` + +3. Build Your Plugin + +Compile your plugin into a WebAssembly component with DUB: + +```sh +dub build -b release -a wasm32-wasip2 +``` + +This will produce `pumpkin-plugin-example.wasm` in the project root ready to be loaded into Pumpkin. diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..1fc157c --- /dev/null +++ b/example/.gitignore @@ -0,0 +1,18 @@ +.dub +docs.json +__dummy.html +docs/ +/pumpkin-plugin-example +pumpkin-plugin-example.wasm +pumpkin-plugin-example.so +pumpkin-plugin-example.dylib +pumpkin-plugin-example.dll +libpumpkin-plugin-example.a +pumpkin-plugin-example.a +pumpkin-plugin-example.lib +pumpkin-plugin-example-test-* +*.exe +*.pdb +*.o +*.obj +*.lst diff --git a/example/dub.json b/example/dub.json new file mode 100644 index 0000000..7b24803 --- /dev/null +++ b/example/dub.json @@ -0,0 +1,21 @@ +{ + "name": "pumpkin-plugin-example", + "description": "A minimal Pumpkin plugin built with D.", + "license": "proprietary", + "authors": ["You"], + "copyright": "Copyright © 2026, You", + + "dependencies": { "pumpkin-api-d": "~>0.1.0" }, + + "targetType": "executable", + "dflags": ["-Xcc=-mexec-model=reactor"], + "buildTypes": { + "debug": { + "buildOptions": ["debugMode", "debugInfo"] + }, + "release": { + "buildOptions": ["optimize", "inline"], + "dflags": ["-L-S"] + } + } +} diff --git a/example/dub.selections.json b/example/dub.selections.json new file mode 100644 index 0000000..fa11d02 --- /dev/null +++ b/example/dub.selections.json @@ -0,0 +1,6 @@ +{ + "fileVersion": 1, + "versions": { + "pumpkin-api-d": "0.1.0" + } +} diff --git a/example/source/app.d b/example/source/app.d new file mode 100644 index 0000000..b707b4d --- /dev/null +++ b/example/source/app.d @@ -0,0 +1,35 @@ +module plugin; + +import wit.pumpkin.plugin.plugin; +import wit.common; +import pumpkin.register; + +struct MyPlugin { + @GetMetadata PluginMetadata getMetadata() + { + immutable(WitString)[$] authors = [ + "You".witList + ]; + + return (immutable PluginMetadata( + name: "pumpkin-plugin-example".witList, + version_: "0.1.0".witList, + authors: authors.witList, + description: "An example plugin in D.".witList, + dependencies: WitList!WitString(), + permissions: WitList!WitString() + )).witClone; + } + + @OnLoad + Result!(void, WitString) onLoad(Context ctx) + { + scope (exit) + ctx.witDrop; // incoming resources need to be cleaned up after they are done being used + + log(Level.info, "Hello from D!".witList); + return ok!WitString; + } +} + +mixin RegisterPlugin!MyPlugin;