konsumer / raylib-wasm

Ideas around a wasm runtime for raylib (to make raylib games in js & browser)
https://konsumer.js.org/raylib-wasm/
MIT License
26 stars 2 forks source link

Typescript typings #9

Open jackwlee01 opened 5 days ago

jackwlee01 commented 5 days ago

Thanks for the great lib! I am glad I found it. I was hoping it would have Typescript typings though.

I had a go at generating Typescript typings with AI (see attached) but there are some issues.

It doesn't seem like it would be too difficult to generate the proper typings for someone with more knowledge of the lib.

raylib.d.ts.txt

konsumer commented 5 days ago

I am just going to say up-front: I have come to be a bit of a typescript-hater.

Short rant about my distaste for typescript - I personally don't use typescript (I find those type popups majorly distracting and very unhelpful.) I am dyslexic, and anything that crams more data into the space where my code is gets disabled immediately, so it has no benefit for me - I don't mix up types, so I am not sure what problem it is meant to solve, other than documentation. Do people really try to call raylib functions with the wrong types? - Pretty much every project that was very largish I have worked on, that I relied on typescript to build, I found tons of stuff that didn't map exactly right, didn't work at all, or used `any` a lot (defeating the stated purpose) like especially DOM/browser APIs around WebGL, and things like that. - I really don't like requiring a build tool, when modern browsers are just cool with ESM, and work well without it.

That said, I am totally hip to adding it, if it helps others, and doesn't hurt things (especially if it's a separate file like this, which is perfect, because I don't have to change build-setup or anything.)

You want to make a PR, so your face is attached to the commit? Happy to merge it. Maybe we could also auto-gen this sort of thing, similar to what I do here.

There are also these classes:

UniformFloat
UniformVector2
UniformVector3
UniformVector4
UniformColor
UniformInt
UniformTexture
definition ```js class UniformFloat { constructor(shader, name, address) { this._shader = shader this._size = 4 this._address = address || mod._malloc(this._size) this._loc = raylib.GetShaderLocation(shader, name) } get value () { return mod.HEAPF32[this._address / 4] } set value (v) { mod.HEAPF32[this._address / 4] = v raylib.SetShaderValue(this._shader, this._loc, this, raylib.SHADER_UNIFORM_FLOAT) } } class UniformVector2 { constructor(shader, name, address) { this._shader = shader this._val = new raylib.Vector2({}, address) this._loc = raylib.GetShaderLocation(shader, name) } get x () { return this._val.x } set x (v) { this._val.x = v raylib.SetShaderValue(this._shader, this._loc, this._val, raylib.SHADER_UNIFORM_VEC2) } get y () { return this._val.y } set y (v) { this._val.y = v raylib.SetShaderValue(this._shader, this._loc, this._val, raylib.SHADER_UNIFORM_VEC2) } } class UniformVector3 { constructor(shader, name, address) { this._shader = shader this._val = new raylib.Vector3({}, address) this._loc = raylib.GetShaderLocation(shader, name) } get x () { return this._val.x } set x (v) { this._val.x = v raylib.SetShaderValue(this._shader, this._loc, this._val, raylib.SHADER_UNIFORM_VEC3) } get y () { return this._val.y } set y (v) { this._val.y = v raylib.SetShaderValue(this._shader, this._loc, this._val, raylib.SHADER_UNIFORM_VEC3) } get z () { return this._val.z } set y (v) { this._val.z = v raylib.SetShaderValue(this._shader, this._loc, this._val, raylib.SHADER_UNIFORM_VEC3) } } class UniformVector4 { constructor(shader, name, address) { this._shader = shader this._val = new raylib.Vector4({}, address) this._loc = raylib.GetShaderLocation(shader, name) } get x () { return this._val.x } set x (v) { this._val.x = v raylib.SetShaderValue(this._shader, this._loc, this._val, raylib.SHADER_UNIFORM_VEC4) } get y () { return this._val.y } set y (v) { this._val.y = v raylib.SetShaderValue(this._shader, this._loc, this._val, raylib.SHADER_UNIFORM_VEC4) } get z () { return this._val.z } set y (v) { this._val.z = v raylib.SetShaderValue(this._shader, this._loc, this._val, raylib.SHADER_UNIFORM_VEC4) } get w () { return this._val.w } set w (v) { this._val.w = v raylib.SetShaderValue(this._shader, this._loc, this._val, raylib.SHADER_UNIFORM_VEC4) } } class UniformColor { constructor(shader, name, address) { this._shader = shader this._val = new raylib.Vector4({}, address) this._loc = raylib.GetShaderLocation(shader, name) } get r () { return this._val.x } set r (v) { this._val.x = v raylib.SetShaderValue(this._shader, this._loc, this._val, raylib.SHADER_UNIFORM_VEC4) } get g () { return this._val.y } set g (v) { this._val.y = v raylib.SetShaderValue(this._shader, this._loc, this._val, raylib.SHADER_UNIFORM_VEC4) } get b () { return this._val.z } set b (v) { this._val.z = v raylib.SetShaderValue(this._shader, this._loc, this._val, raylib.SHADER_UNIFORM_VEC4) } get a () { return this._val.w } set a (v) { this._val.w = v raylib.SetShaderValue(this._shader, this._loc, this._val, raylib.SHADER_UNIFORM_VEC4) } } class UniformInt { constructor(shader, name, address) { this._shader = shader this._size = 4 this._address = address || mod._malloc(this._size) this._loc = raylib.GetShaderLocation(shader, name) } get value () { return mod.HEAP32[this._address / 4] } set value (v) { mod.HEAP32[this._address / 4] = v raylib.SetShaderValue(this._shader, this._loc, this, raylib.SHADER_UNIFORM_INT) } } class UniformTexture { constructor (shader, name, address) { this._shader = shader this._loc = raylib.GetShaderLocation(shader, name) } set texture (t) { raylib.SetShaderValueTexture(this._shader, this._loc, t) } } ```

which are special classes for doing stuff with shaders, that are not in C raylib.

konsumer commented 5 days ago

I have also been thinking about simplifying the build in general. I have been playing with some sort of related ideas over here. It's got a long way to go, but the code-gen and the C build setup is much nicer.

konsumer commented 5 days ago

I am not totally positive what types you hope for, but I build everything from these defs so feel free to feed that to AI to get typescript defs. They probably won't be perfect (since it's C types) but maybe I could generate a more standalone js file you can use regular typescript tooling on?

jackwlee01 commented 4 days ago

Awesome, thanks for linking those defs. I’ll give it a try with those, and your codegen code, to see how that works.

The types that I would hope for is at least everything on the Raylib cheat sheet.

Just quickly looking through your examples, it appears that the JavaScript interface is basically the same as the C interface. Are there many instances where the interface deviates?

jackwlee01 commented 4 days ago

Also, I really like that your lib does not need a build step. This makes it absolutely fantastic as a teaching tool.

I’ll mention how I intend to use your lib. I have node.js installed on my system. My project does not have a package.json or any dependencies, but I run the command npx vite in my project directory. This gives me a nice minimal development setup with auto reloading, and also facilitates using typescript source files. This feels like writing vanilla javascript, but with a few extra nice development tools.

konsumer commented 4 days ago

The types that I would hope for is at least everything on the Raylib cheat sheet.

That makes perfect sense to me. I should be able to help with the code-gen in a bit. I think we can probly leverage some of the js mapping that I already have, and as I said, I have some ideas to simplify/improve, anyway. Give it a go first, if you want, but I am happy to help.

Are there many instances where the interface deviates?

Anything that loads files should use a promise (use await) so it can load images & things from URLs, but otherwise it should all match.

This gives me a nice minimal development setup with auto reloading, and also facilitates using typescript source files. This feels like writing vanilla javascript, but with a few extra nice development tools.

Exactly! I have been doing this with a bunch of my personal projects, lately, because I miss that immediacy and spirit of play. I don't need to plan out a project/build/deploy to just get things working quickly, and I can try out ideas and move on to other things.

Here are a couple other related tricks for that sort of workflow:

jackwlee01 commented 3 days ago

Thanks! I’ll see if I get time this week to look at the typings again.

I hadn’t heard of ems.sh, but it looks really awesome. I’m not sure how it would play with Typescript but seems ideal for my quick, one off experiments. Thanks for the tip :)