Not finished WFC
This commit is contained in:
parent
665892a798
commit
8a9b437ae7
|
|
@ -0,0 +1,3 @@
|
|||
IndentWidth: 4
|
||||
ColumnLimit: 240
|
||||
PointerAlignment: Left
|
||||
|
|
@ -103,8 +103,7 @@ bun run build
|
|||
sudo apt install clang lld wabt
|
||||
```
|
||||
- Supports only function exports & `memory`
|
||||
- exported all non-static functions
|
||||
- no stdlib
|
||||
- No stdlib
|
||||
|
||||
|
||||
## Publishing
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#define BLOCK_SIZE (64 * 1024)
|
||||
#define BLOCK_1MB 16
|
||||
|
||||
static uintptr_t bump_pointer = (uintptr_t)&__heap_base;
|
||||
static uintptr_t heap_end = BLOCK_1MB * BLOCK_SIZE;
|
||||
IMPORT(grow) void grow(uint32_t blocks);
|
||||
|
||||
static void* bump_alloc(uintptr_t n) {
|
||||
uintptr_t r = bump_pointer;
|
||||
bump_pointer += n;
|
||||
|
||||
while (bump_pointer >= heap_end) {
|
||||
grow(heap_end / BLOCK_SIZE);
|
||||
heap_end *= 2;
|
||||
}
|
||||
|
||||
return (void*)r;
|
||||
}
|
||||
|
||||
void* malloc(uintptr_t n) {
|
||||
return bump_alloc(n);
|
||||
}
|
||||
|
||||
void free(void* p) { (void)p; }
|
||||
|
||||
void* memset(void* s, uint8_t c, uint32_t n) {
|
||||
uint8_t* p = (uint8_t*)s;
|
||||
while (n--) {
|
||||
*p++ = c;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void* memcpy(void* dest, const void* src, uint32_t n) {
|
||||
uint8_t* d = (uint8_t*)dest;
|
||||
const uint8_t* s = (const uint8_t*)src;
|
||||
while (n--) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
int memcmp(const void* s1, const void* s2, uint32_t n) {
|
||||
const uint8_t* p1 = (const uint8_t*)s1;
|
||||
const uint8_t* p2 = (const uint8_t*)s2;
|
||||
|
||||
while (n--) {
|
||||
if (*p1 != *p2) {
|
||||
return (*p1 - *p2);
|
||||
}
|
||||
p1++;
|
||||
p2++;
|
||||
}
|
||||
|
||||
return 0; // Memory blocks are equal
|
||||
}
|
||||
|
||||
static uint64_t rand_state;
|
||||
|
||||
void srand(uint64_t seed) { rand_state = seed; }
|
||||
|
||||
uint64_t rand(void) {
|
||||
uint64_t z = (rand_state += 0x9e3779b97f4a7c15);
|
||||
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
|
||||
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
|
||||
return z ^ (z >> 31);
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
extern unsigned char __heap_base;
|
||||
|
||||
#define IMPORT(name) __attribute__((import_module("env"), import_name(#name)))
|
||||
#define EXPORT(name) __attribute__((export_name(#name)))
|
||||
|
||||
EXPORT(malloc) void* malloc(uintptr_t);
|
||||
void free(void*);
|
||||
|
||||
void* memset(void* s, uint8_t c, uint32_t n);
|
||||
void* memcpy(void* dest, const void* src, uint32_t n);
|
||||
int memcmp(const void* s1, const void* s2, uint32_t n);
|
||||
|
||||
IMPORT(log) void print_int(int64_t);
|
||||
|
||||
EXPORT(__srand) void srand(uint64_t seed);
|
||||
uint64_t rand(void);
|
||||
|
|
@ -3,7 +3,7 @@ import { $ } from 'bun';
|
|||
import path from 'path';
|
||||
import fs from 'fs/promises';
|
||||
import { buildHTML } from "./html";
|
||||
import inquirer from 'inquirer';
|
||||
import select from '@inquirer/select';
|
||||
import { isGame, getGames } from './isGame';
|
||||
|
||||
const outDir = path.resolve(import.meta.dir, '..', '..', 'dist');
|
||||
|
|
@ -13,12 +13,10 @@ let game = process.argv[2];
|
|||
const publish = process.env.PUBLISH_LOCATION;
|
||||
|
||||
while (!await isGame(game)) {
|
||||
const answer = await inquirer.prompt([{
|
||||
type: 'list',
|
||||
name: 'game',
|
||||
choices: await getGames(),
|
||||
}]);
|
||||
game = answer.game;
|
||||
const game = await select({
|
||||
message: 'Game to build:',
|
||||
choices: (await getGames()).map(value => ({ value })),
|
||||
});
|
||||
}
|
||||
|
||||
const html = await buildHTML(game, true);
|
||||
|
|
|
|||
|
|
@ -15,13 +15,34 @@ const wasmPlugin = ({ production, portable }: WasmLoaderConfig = {}): BunPlugin
|
|||
let wasmPath = path.resolve(import.meta.dir, '..', '..', 'dist', 'tmp.wasm');
|
||||
let jsContent: string = `
|
||||
async function instantiate(url) {
|
||||
const { instance } = await WebAssembly.instantiateStreaming(fetch(url));
|
||||
const memory = new WebAssembly.Memory({
|
||||
initial: 16,
|
||||
});
|
||||
let data = new DataView(memory.buffer);
|
||||
const { instance } = await WebAssembly.instantiateStreaming(fetch(url), {
|
||||
env: {
|
||||
memory,
|
||||
log(...args) {
|
||||
console.log('[wasm]', ...args);
|
||||
},
|
||||
grow(blocks) {
|
||||
if (blocks > 0) {
|
||||
memory.grow(blocks);
|
||||
data = new DataView(memory.buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
...instance.exports,
|
||||
data: new DataView(instance.exports.memory.buffer),
|
||||
memory,
|
||||
get data() { return data; },
|
||||
};
|
||||
}
|
||||
const module = await instantiate(new URL("tmp.wasm", import.meta.url));
|
||||
const module = await instantiate(new URL($WASM$));
|
||||
if (typeof module.__srand === 'function') module.__srand(BigInt(Date.now()));
|
||||
|
||||
export default module;
|
||||
`;
|
||||
if (args.path.endsWith('.ts')) {
|
||||
|
|
@ -49,7 +70,11 @@ const wasmPlugin = ({ production, portable }: WasmLoaderConfig = {}): BunPlugin
|
|||
} else if (args.path.endsWith('.wasm')) {
|
||||
wasmPath = args.path;
|
||||
} else {
|
||||
const result = await $`clang --target=wasm32 -O3 --no-standard-libraries -Wl,--export-all -Wl,--no-entry -fno-builtin -o ${wasmPath} ${args.path}`;
|
||||
const buildAssets = path.resolve(import.meta.dir, 'assets');
|
||||
const stdlib = `${buildAssets}/stdlib.c`;
|
||||
const opt = production ? '-O3': '-O0';
|
||||
const result = await $`clang --target=wasm32 ${opt} -flto -fno-builtin --no-standard-libraries -I ${buildAssets} -Wall -Wextra -Wpedantic -Werror -Wl,--lto-O3 -Wl,--no-entry -Wl,--import-memory -o ${wasmPath} ${args.path} ${stdlib}`;
|
||||
|
||||
if (result.exitCode !== 0) {
|
||||
throw new Error('Compile failed, check output');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
--target=wasm32
|
||||
-fno-builtin
|
||||
--no-standard-libraries
|
||||
-I
|
||||
build/assets/
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wpedantic
|
||||
-Werror
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
"build": "bun build/build.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@inquirer/select": "2.3.10",
|
||||
"classnames": "2.5.1",
|
||||
"preact": "10.22.0"
|
||||
},
|
||||
|
|
@ -18,7 +19,6 @@
|
|||
"assemblyscript": "0.27.29",
|
||||
"bun-lightningcss": "0.2.0",
|
||||
"html-minifier": "4.0.0",
|
||||
"inquirer": "9.3.4",
|
||||
"typescript": "5.5.2",
|
||||
"uglify-js": "3"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { render } from "preact";
|
||||
import type { Display } from ".";
|
||||
import { clamp, range } from "@common/utils";
|
||||
import classNames from "classnames";
|
||||
|
||||
|
|
@ -18,7 +17,7 @@ export interface BrickDisplayImage {
|
|||
height: number;
|
||||
}
|
||||
|
||||
export class BrickDisplay implements Display {
|
||||
export class BrickDisplay {
|
||||
#field: boolean[] = new Array(FIELD_HEIGHT * FIELD_WIDTH);
|
||||
#miniField: boolean[] = new Array(MINI_FIELD_HEIGHT * MINI_FIELD_WIDTH);
|
||||
#score: number = 0;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
export function createCanvas(width: number, height: number) {
|
||||
const canvas = document.createElement('canvas');
|
||||
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
canvas.style.height = '100%';
|
||||
canvas.style.imageRendering = 'pixelated';
|
||||
|
||||
document.body.style.display = 'flex';
|
||||
document.body.style.justifyContent = 'center';
|
||||
document.body.append(canvas);
|
||||
|
||||
return canvas;
|
||||
}
|
||||
|
||||
export function getImageData(image: HTMLImageElement): ImageData {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = image.naturalWidth;
|
||||
canvas.height = image.naturalHeight;
|
||||
const ctx = canvas.getContext('2d')!;
|
||||
ctx.drawImage(image, 0, 0);
|
||||
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
|
||||
return imageData;
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
export interface Display {
|
||||
init(): void;
|
||||
update(): void;
|
||||
}
|
||||
|
||||
export { BrickDisplay, type BrickDisplayImage } from './brick';
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { BrickDisplay } from "@common/display";
|
||||
import { BrickDisplay } from "@common/display/brick";
|
||||
import { isPressed, updateKeys } from "@common/input";
|
||||
|
||||
import spritesheetImage from './assets/spritesheet.png';
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { createCanvas } from "@common/display/canvas";
|
||||
import life from "./life.c";
|
||||
|
||||
const width = life.getWidth();
|
||||
const height = life.getHeight();
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
const canvas = createCanvas(width, height);
|
||||
const context = canvas.getContext('2d')!;
|
||||
const imageData = context.createImageData(width, height);
|
||||
|
||||
|
|
@ -12,15 +13,7 @@ const step = life.step as CallableFunction;
|
|||
const pixels = new Uint8Array(life.memory.buffer, life.getPixels(), width * height * 4);
|
||||
|
||||
export default function main() {
|
||||
document.body.append(canvas);
|
||||
initField(Date.now());
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
canvas.style.height = '100%';
|
||||
canvas.style.imageRendering = 'pixelated';
|
||||
|
||||
document.body.style.display = 'flex';
|
||||
document.body.style.justifyContent = 'center';
|
||||
|
||||
console.log(life, pixels.length);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ void* malloc(uint32_t n);
|
|||
static uint8_t rand8(void);
|
||||
static int countNeighbours(int x, int y);
|
||||
|
||||
int getWidth() { return width; }
|
||||
int getHeight() { return height; }
|
||||
uint8_t* getPixels() { return pixels; }
|
||||
int getWidth(void) { return width; }
|
||||
int getHeight(void) { return height; }
|
||||
uint8_t* getPixels(void) { return pixels; }
|
||||
|
||||
void step()
|
||||
void step(void)
|
||||
{
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
|
|
@ -76,7 +76,7 @@ static uint8_t rand_state[STATE_BYTES] = { 0x87, 0xdd, 0xdc, 0x10, 0x35, 0xbc, 0
|
|||
static uint8_t rand8(void)
|
||||
{
|
||||
static uint16_t c = 0x42;
|
||||
static int i = 0;
|
||||
static uint32_t i = 0;
|
||||
uint16_t t;
|
||||
uint8_t x;
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 204 B |
|
|
@ -0,0 +1,43 @@
|
|||
import wfc from './wfc.c';
|
||||
import wfcImage from './assets/wfc.png';
|
||||
import { createCanvas, getImageData } from "@common/display/canvas"
|
||||
|
||||
const width = 256;
|
||||
const height = 256;
|
||||
|
||||
const canvas = createCanvas(width, height);
|
||||
const context = canvas.getContext('2d')!;
|
||||
const imageData = context.createImageData(width, height);
|
||||
let pixels: Uint8ClampedArray;
|
||||
|
||||
export default function main() {
|
||||
console.log(wfc);
|
||||
|
||||
const imageData = getImageData(wfcImage);
|
||||
const dataPtr = wfc.malloc(imageData.data.length);
|
||||
let buffer = new Uint8ClampedArray(wfc.memory.buffer, dataPtr, imageData.data.length);
|
||||
buffer.set(imageData.data);
|
||||
|
||||
wfc.init(dataPtr, imageData.width, imageData.height, canvas.width, canvas.height);
|
||||
pixels = new Uint8ClampedArray(wfc.memory.buffer, wfc.getPixels(), width * height * 4);
|
||||
requestAnimationFrame(loop);
|
||||
}
|
||||
|
||||
let sum = 0;
|
||||
let count = 0;
|
||||
|
||||
async function loop() {
|
||||
const start = performance.now();
|
||||
wfc.step();
|
||||
const end = performance.now();
|
||||
|
||||
sum += end - start;
|
||||
count++;
|
||||
|
||||
imageData.data.set(pixels);
|
||||
|
||||
context.putImageData(imageData, 0, 0);
|
||||
context.clearRect(0, 0, 35, 15);
|
||||
context.fillText(`${(sum / count).toFixed(1)} ms`, 2, 10);
|
||||
requestAnimationFrame(loop);
|
||||
}
|
||||
|
|
@ -0,0 +1,212 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#define PATTERN_SIZE 3
|
||||
#define PATTERN_BATCH 8
|
||||
|
||||
typedef struct {
|
||||
uint32_t neighbours[9];
|
||||
} pattern_t;
|
||||
|
||||
typedef struct {
|
||||
/** pattern indices */
|
||||
uint32_t* possibilities;
|
||||
uint32_t num_possibilities;
|
||||
} superposition_t;
|
||||
|
||||
typedef enum { NORTH, EAST, SOUTH, WEST, DIRECTION_MAX } direction_t;
|
||||
|
||||
pattern_t* patterns;
|
||||
uint32_t num_patterns;
|
||||
|
||||
uint32_t* pixels;
|
||||
superposition_t* superpositions;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
|
||||
void patterns_init(uint32_t* pixel_data, uint16_t image_width, uint16_t image_height);
|
||||
void superposition_init(void);
|
||||
|
||||
EXPORT(init) void init(uint32_t* pixel_data, uint16_t image_width, uint16_t image_height, uint16_t canvas_width, uint16_t canvas_height) {
|
||||
width = canvas_width;
|
||||
height = canvas_height;
|
||||
|
||||
patterns_init(pixel_data, image_width, image_height);
|
||||
superposition_init();
|
||||
}
|
||||
|
||||
pattern_t pattern_extract(uint32_t* pixel_data, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t batch) {
|
||||
pattern_t pattern = {0};
|
||||
|
||||
for (uint8_t i = 0; i < PATTERN_SIZE * PATTERN_SIZE; i++) {
|
||||
int8_t dx = (i % PATTERN_SIZE) - (PATTERN_SIZE / 2);
|
||||
int8_t dy = (i / PATTERN_SIZE) - (PATTERN_SIZE / 2);
|
||||
|
||||
int8_t tmp;
|
||||
|
||||
if (batch == 1) { // horizontal flip
|
||||
dx = PATTERN_SIZE - dx;
|
||||
} else if (batch == 2) { // vertical flip
|
||||
dy = PATTERN_SIZE - dy;
|
||||
} else if (batch == 3) { // both flips
|
||||
dx = PATTERN_SIZE - dx;
|
||||
dy = PATTERN_SIZE - dy;
|
||||
} else if (batch == 4) { // rotate 90
|
||||
tmp = dx;
|
||||
dx = dy;
|
||||
dy = PATTERN_SIZE - tmp;
|
||||
} else if (batch == 5) { // rotate 270
|
||||
tmp = dy;
|
||||
dy = dx;
|
||||
dx = PATTERN_SIZE - tmp;
|
||||
} else if (batch == 6) { // flip main axis
|
||||
tmp = dy;
|
||||
dy = dx;
|
||||
dx = tmp;
|
||||
} else if (batch == 7) { // flip secondary axis
|
||||
tmp = dy;
|
||||
dy = PATTERN_SIZE - dx;
|
||||
dx = PATTERN_SIZE - tmp;
|
||||
}
|
||||
|
||||
uint16_t xx = (x + dx + width) % width;
|
||||
uint16_t yy = (y + dy + height) % height;
|
||||
|
||||
uint32_t idx = xx + yy * width;
|
||||
pattern.neighbours[i] = pixel_data[idx];
|
||||
}
|
||||
return pattern;
|
||||
}
|
||||
|
||||
bool pattern_check(pattern_t pattern) {
|
||||
for (uint32_t i = 0; i < num_patterns; i++) {
|
||||
if (memcmp(&pattern, &patterns[i], sizeof(pattern)) == 0) {
|
||||
return false; // found duplicate
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void patterns_init(uint32_t* pixel_data, uint16_t image_width, uint16_t image_height) {
|
||||
uint32_t max_patterns = image_width * image_height * PATTERN_BATCH;
|
||||
patterns = malloc(max_patterns * sizeof(*patterns));
|
||||
|
||||
num_patterns = 0;
|
||||
|
||||
for (uint16_t y = 0; y < image_height; y++) {
|
||||
for (uint16_t x = 0; x < image_width; x++) {
|
||||
for (uint8_t batch = 0; batch < PATTERN_BATCH; batch++) {
|
||||
pattern_t pattern = pattern_extract(pixel_data, x, y, image_width, image_height, batch);
|
||||
if (pattern_check(pattern)) {
|
||||
patterns[num_patterns++] = pattern;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print_int(num_patterns);
|
||||
print_int(max_patterns);
|
||||
}
|
||||
|
||||
void superposition_init(void) {
|
||||
pixels = malloc(width * height * sizeof(*pixels));
|
||||
superpositions = malloc(width * height * sizeof(*superpositions));
|
||||
|
||||
for (uint32_t i = 0; i < width * height; i++) {
|
||||
superposition_t superposition = {
|
||||
.num_possibilities = num_patterns,
|
||||
.possibilities = malloc(num_patterns * sizeof(uint32_t)),
|
||||
};
|
||||
|
||||
for (uint32_t p = 0; p < num_patterns; p++) {
|
||||
superposition.possibilities[p] = p;
|
||||
}
|
||||
|
||||
superpositions[i] = superposition;
|
||||
}
|
||||
}
|
||||
|
||||
bool pattern_match(pattern_t a, pattern_t b, direction_t direction) {
|
||||
switch (direction) {
|
||||
case NORTH:
|
||||
for (uint8_t x = 0; x < PATTERN_SIZE; x++) {
|
||||
if (a.neighbours[x] != b.neighbours[PATTERN_SIZE * (PATTERN_SIZE - 1) + x]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
case EAST:
|
||||
for (uint8_t y = 0; y < PATTERN_SIZE; y++) {
|
||||
if (a.neighbours[y * PATTERN_SIZE + PATTERN_SIZE - 1] != b.neighbours[y * PATTERN_SIZE]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
case SOUTH:
|
||||
for (uint8_t x = 0; x < PATTERN_SIZE; x++) {
|
||||
if (a.neighbours[PATTERN_SIZE * (PATTERN_SIZE - 1) + x] != b.neighbours[x]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
case WEST:
|
||||
for (uint8_t y = 0; y < PATTERN_SIZE; y++) {
|
||||
if (a.neighbours[y * PATTERN_SIZE] != b.neighbours[y * PATTERN_SIZE + PATTERN_SIZE - 1]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void superposition_remove(superposition_t* superposition, uint32_t pattern) {
|
||||
uint32_t i;
|
||||
for (i = 0; i < superposition->num_possibilities; i++) {
|
||||
if (superposition->possibilities[i] == pattern)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < superposition->num_possibilities) {
|
||||
for (; i < superposition->num_possibilities - 1; i++) {
|
||||
superposition->possibilities[i] = superposition->possibilities[i + 1];
|
||||
}
|
||||
superposition->num_possibilities--;
|
||||
}
|
||||
}
|
||||
|
||||
void superpositions_draw(void) {
|
||||
for (uint32_t i = 0; i < width * height; i++) {
|
||||
uint64_t sum = 0;
|
||||
superposition_t superposition = superpositions[i];
|
||||
for (uint32_t p = 0; p < superposition.num_possibilities; p++) {
|
||||
sum += patterns[superposition.possibilities[p]].neighbours[(PATTERN_SIZE * PATTERN_SIZE) / 2];
|
||||
}
|
||||
if (superposition.num_possibilities > 0) {
|
||||
pixels[i] = sum / superposition.num_possibilities;
|
||||
} else {
|
||||
pixels[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void superpositions_propagate(void) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void superposition_collapse(superposition_t* superposition) {
|
||||
if (superposition->num_possibilities > 1) {
|
||||
uint32_t choice = rand() % superposition->num_possibilities;
|
||||
superposition->possibilities[0] = superposition->possibilities[choice];
|
||||
superposition->num_possibilities = 1;
|
||||
|
||||
superpositions_propagate();
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT(step) void step(void) {
|
||||
superposition_collapse(&superpositions[420]);
|
||||
superpositions_draw();
|
||||
}
|
||||
|
||||
EXPORT(getPixels) uint32_t* get_pixels(void) { return pixels; }
|
||||
|
|
@ -48,6 +48,8 @@ declare module "*.c" {
|
|||
const instance: {
|
||||
memory: WebAssembly.Memory;
|
||||
data: DataView;
|
||||
malloc: (size: number) => number;
|
||||
free: (ptr: number) => void;
|
||||
|
||||
[x: string]: (...args: any) => any;
|
||||
};
|
||||
|
|
@ -57,6 +59,8 @@ declare module "*.cpp" {
|
|||
const instance: {
|
||||
memory: WebAssembly.Memory;
|
||||
data: DataView;
|
||||
malloc: (size: number) => void;
|
||||
free: (ptr: number) => void;
|
||||
|
||||
[x: string]: (...args: any) => any;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue