#Gaylib - Raylib functionnal bindings in Gleam

1 messages ยท Page 1 of 1 (latest)

slim granite
#

There

#

so

#

I get your point with the shapes

#

I keep forgetting variables are immutable in gleam

#

so it actually does make sense with that argument

#

I think?

#

it's just funny btw

#

I almost finished copying all raylib functions in gleam

#

and now have to start over

#

mostly

#

๐Ÿ˜ญ

dusky vector
#

the API Louis said made sense to me -

rl.drawing([
  rl.Text("Hello world", 190, 200, 20, rl.LIGHT_GREY),
  rl.Text("Hello world 2!", 190, 240, 20, rl.RED),
])
#

it's basically what raylib looks like normally

slim granite
#

I don't know

dusky vector
#

actually it's LIGHTGRAY isn't it

#

wtv

slim granite
#

yeah wtv

#

but there you go

slim granite
#

it almost looks too simplistic to do anything with it

dusky vector
slim granite
#

yes

#

but

still saffron
slim granite
#

then you might introduce a camera, shading

slim granite
#

html is very "simple"

#

one parent many childs

#

this works with UIs pretty well too

#

but that's for a game/graphics library

#

there are more things to it

#

like usually you would have to

BeginShaderMode(shader)
BeginMode3D(camera)
BeginDrawing()
   // ...
// End...
#

with that API you can't do that

still saffron
# slim granite one parent many childs

i mean

rl.drawing([ // basically BeginDrawing()
  rl.Text("Hello world", 190, 200, 20, rl.LIGHT_GREY),
  rl.Text("Hello world 2!", 190, 240, 20, rl.RED),
]) // basically EndDrawing()
slim granite
#

that works when it's simple

dusky vector
#
rl.drawing([
  rl.Camera2D(target: rl.Vec2(100, 100), rotation: 40.0, zoom: 1.0, draws: [
    rl.Rectangle(...),
    rl.Rectangle(...),
    rl.Rectangle(...),
  ]),
  rl.Text(...),
])
slim granite
#

what

#

that's not how it works

dusky vector
#

why not? this is your api

slim granite
#

but

#

I don't understand how the fuck you're supposed to use that to then make the proper calls to raylib

#

like what if the user passes in two cameras

#

and wtf are the argument rl.drawing takes

dusky vector
#

if drawcall == camera2d then do_calls() pseudocode

slim granite
#

what

#

@-@

#

I don't understand how all of that makes any single inch of sense

#

you don't do BeginDrawing and then BeginMode2D

#

you do the opposite

dusky vector
#
type DrawCall {
  Camera2D(...)
  Text(...)
  Rectangle(...)
}

pub fn drawing(draws: List(DrawCall))
slim granite
#

this implies the opposite

dusky vector
slim granite
#

what

dusky vector
slim granite
#

...

#

wtf

#

why am I the one doing this

#

I always thought it was the opposite

still saffron
slim granite
#

that i know

#

i just

#

i don't even know how to use raylib

#

i should just stop

#

sorry

#

i was trying to not get angry at myself and sad and all

#

i'm good

#

I'm gonna mostly restart everything and try those ideas thx

#

mh

#

wait

#

actually this doesn't fix my main issue

#

the main loop is usually not a single "phase"

#

there's also the event handling

#

like key/button press and stuff

#

in C you call one function, take its result and do stuff accordingly

#

you can't just do that here

#

as I said the goal would be to do a single call per frame

#

I see how it could be possible to have like a bit

#

2 to 5

#

but 1

#

that seems impossible here

#

again I don't have the functionnal programming logic at all i'm bad at it

#

so i'm surely just blind

dusky vector
#
while (!WindowShouldClose()) {
  if (IsKeyDown(KEY_RIGHT)) { ... }

  BeginDrawing();
    ...
  EndDrawing();
}
type Model {
  Model(...)
}

fn view(model: Model) {
    rl.drawing([
      ...    
    ])
}

fn update(event: rl.Event, model: Model) -> Model {
  case event {
    rl.KeyDown(rl.KEY_RIGHT) -> { ... }
    _ -> model
  }
}

fn main() {
  rl.run(update, view)
}
```i'd prob start by modelling it using MVU/MVU-adjacent stuff, maybe like this? you collate all the events for that frame, pass them to gleam and then gleam can either handle them 1-by-1 like i showed here or you could pass a `List(rl.Event)` and handle them like that?
#

just spitballing ideas

slim granite
#

well I mean

#

it's a good idea

#

but there's a big problem

#

just using WindowShouldClose might work in simple cases

#

but in some cases it shouldn't exit

#

in some other cases you might want another event to do it

#

and I don't see how update should return a Model?-

dusky vector
#

you update the model

slim granite
#

what?

#

what model

dusky vector
#

the model is then represented by the view

#

any model

slim granite
#

aaaaaaaaaaaaaa

dusky vector
#

it's a generic

still saffron
slim granite
#

you don't mean a 3D model

slim granite
dusky vector
#

your API doesn't care about what the state of the user's application is

dusky vector
slim granite
#

yeah sorry

#

it's confusing

#

to me at least lol

#

cuz

dusky vector
#

i think taking a look at lustre would honestly help

slim granite
#

probably

dusky vector
slim granite
#

gosh

#

it reminds me of MVC

dusky vector
#

...

slim granite
#

separation of concern shit

#

tho

#

here

#

it seems needed lol

slim granite
#

i know

#

it's basically the same idea

dusky vector
#

mhm

slim granite
#

sorry

dusky vector
#

don't be

slim granite
#

too late

worldly mango
slim granite
#

yes yes lol

#

i got that

worldly mango
#

I think, seeing the C produced that indeed, lustre's approach would make it REALLY nice and approachable. These would be so good.

slim granite
#

i'm trying

dusky vector
#

excluding the background buildings because โœจ time โœจ, i imagine that the "2d camera" example at https://raylib.com/examples.html could look like this

there's probably some syntax errors here as i typed it in a text editor without the API actually existing

proper osprey
#

SREEN AREA

#

my favourite area

dusky vector
#

and spelling mistakes then ๐Ÿ˜‚

slim granite
#

I see

#

interesting

#

mmh

#

you can't... save the window?

#

in raylib it's not exposed

#

or is it?

#

ooooh

#

I see what you did with the State

dusky vector
#

then in C you grab the value and just

InitWindow(window.width, window.height, window.title)
slim granite
#

i see what you mean

dusky vector
#

i'd make an example impl but i have 0 clue how to do NIFs

slim granite
#

dw i'll do it

#

i know what you mean

dusky vector
#

i looked into it for like 20mins before my d&d session and decided it was over my pay grade

slim granite
#

haha

#

it's truly annoying ik

dusky vector
#

i mean i find C on it's own a pain in the arse so

slim granite
#

a

#

well then don't do that lol

#

it's not easily doable with something else

slim granite
#

and then call update with all of em

#

idk

#

the way you did it it looks like update is called per event not per frames?

dusky vector
slim granite
#

ooop

#

wait you did?

#

then i don't understand

#

ahh

#

ok

slim granite
slim granite
#

so I know it's for what we're going, but I made this work

pub fn main() {
  init_window(800, 600, charlist.from_string("RayGleam"), 60)
  drawing([
    Background(Color(255, 0, 0, 255))
  ])
  close_window()
}
#

obviously the window closes instantly

#

but it's something!

#

(the C is a mess, i'm glad I made some macros)

slim granite
#

I need to make a logo for raygleam one day

slim granite
#

it looks off putting

still saffron
#

gaylib :3

slim granite
#

not legible sadly

proper osprey
#

what if you give it a black border around the pride colors

slim granite
#

good idea

#

and since it's gay

#

this makes more sense

#

it's not lucy

#

it's...

proper osprey
#

glucy

slim granite
#

idk the first name that came to mind is jared

#

so it's jared

still saffron
#

luke

proper osprey
#

chad

slim granite
#

jared the gay lib

#

i like jared

#

so it's gonna be jared

#

:3

#

i like it but idk it's not great

#

you made me rename raygleam to gaylib

#

jeez

#

alright

#

refactor

#

and then i'll commit the first thingy

slim granite
#

there!

#

i'm done for today

slim granite
#

Gaylib - Raylib functionnal bindings in Gleam

worldly mango
#

hehe

slim granite
#

?

worldly mango
#

the name chamge is official now

bleak trellis
slim granite
#

nuh

#

it doesn't look like this normaly wait

#

it's a font problem

#

lemme fix it

#

i think it's good now

bleak trellis
#

yep it's good now

slim granite
#

great

slim granite
#

Alr, so I've been working a bit on it today

#

(gl is for gaylib)

#

it's clearly impractical for now since the events are a list

#

but at least it works

#

And keypress too

#
fn update(state: State, update: gl.Update) -> #(State, List(gl.Action)) {
  let actions = case list.contains(update.events, gl.WindowShouldClose) {
    True -> [gl.Close]
    False -> []
  }

  let time = case list.contains(update.events, gl.KeyPressed(gl.R)) {
    False -> state.time +. update.dt  /. 1.5
    True -> 0.
  }
  #(State(
    gl.Vec4(
      x: maths.sin({ time *. 2. } +. 1.),
      y: maths.sin({ time *. 2. +. 2. } +. 1.),
      z: maths.sin({ time *. 2. +. 4. } +. 1.),
      w: 1.,
    )
    |> gl.vec4_to_color,
    time:
  ), actions)
}
#

This example update function basically make the background_colorfield of State rotate between red, green, and blue

#

and when pressing R it resets the timer

#

and since the whole math is based on it

#

it starts again

#

dumb example I know

#

but showcases what you can do for now :3

#

However I'm having a big big issue

#

for most of the other input events, unless checking every single key/button, you can't know if it was Released, if it Down, etc...

#

all key presses done in a single frame are easily accessible in raylib with the GetKeyPressed() function

#

it returns the last element in the list of key presses in current frame and pops it

#

or returns 0 if that list is empty

#

which allows me to create a dynamic array of key pressed in C to then make an erlang list

#

however you cannot do that for the key that are down

#

so I have to do at least 109 function calls (for each keyboard key currently down)

#

sounds a bit uhm

#

much

#

so idk if it's the right approach

worldly mango
#

Maybe a variant of each press and a function that takes that type

#

on the gleam side that is

slim granite
#

what?

#

i'm unsure of what u mean lel

worldly mango
#

that'd hopefully cut down on the functions you have to write ๐Ÿ˜…

slim granite
#

well yes but I did not understand what you said lol so

#

and it's not about the number of functions i write

#

but I call

#

all of that is still done in one single function

worldly mango
#

are the keys each their own function on the raylib side?

slim granite
#

no

#

it's one single function for each action

#

GetKeyDown, GetKeyPressed, GetKeyReleased

#

no

#

wait

#

IsKeyDown, IsKeyPressed, IsKeyReleased

#

and thx to its convenience I use GetKeyPressed rn

#

but that's only on the frame you press the key

#

unlike IsKeyDown

#

but it has to be done for each key

#

and again that's just for keyboard keys the same has to be done for gamepad buttons

slim granite
#

?

#

the text of the logo is now bigger

#

i think it's more legible

slim granite
#

alr i stop for today

#

I have non sensical issues with NIF so I said f*ck it

slim granite
#

im so dumb

#

C passes copy to functions

#

not reference

#

I got used to rust after using it once

#

shoot

slim granite
#

now that's funny

#

Draws a rectangle with the given rectangle

ocean pagoda
#
pub type Color {
  Color(r: Int, g: Int, b: Int, a: Int)
}

fyi there's a gleam community package for this ^.^

slim granite
#

what?

#

what's the issue?

ocean pagoda
#

there is no issue

slim granite
#

a

ocean pagoda
#

im just pointing out for your information that there's a gleam_cimmunity_colour package

slim granite
#

well maybe but I hate depending on too much things

#

color stuff ain't too hard

#

well

#

i mean

#

for RGB

ocean pagoda
#

i was just pointing it out in case you didnt know and cared.

slim granite
#

yeah thx

#

i'll look into it... maybe

#

but idc :3

#

at least for now

#

since in rl there's a way to use HSV for some stuff, i might have to look into how it's done elsewere

#

cuz I looked into it and gosh I hate HSV and HSL

#

and there's worse ;_;

#

i mean no

#

i love them

#

it's so cool

#

but not the maths

#

sorry if I sounded too cold or anything haha-

slim granite
#

I have no idea how to properly have some kind of "Action" that you can do during the update

#

like move the window, close it, and stuff

#

meh

#

and even Events, they come in as a List

#

which is inpractical lol

#

I looked at Lustre and it helped a bit

#

now you can initialize the window like that

#

which kinda makes more sense

slim granite
#

the game still runs fine at 60 fps

#

but yeah

#

even 144

#

and more so it's fine

#

another issue btw

#

the events are one frame late

#

since I do drawing and getting the events at the same time

#

idk how to explain honestly-

#

i mean it's still pretty cool

#

once FFI call for all of that

#

and also contructing everything from C

#

that's pretty cool

#

NIF is pretty powerful

slim granite
#

Alr so imma pause this for now

#

I'm stuck on the design of the API

#

Tho i'm still fully open to suggestions

#

I don't know functionnal programming enough

#

and Raylib is clearly not made for pure functionnal programming and even less in a VM like BEAM

#

I'm still proud of what I achieved still

#

For example I implemented the possibility to handle runtime errors

#

Which is very practical

#

All function from NIF return a result I construct in C

#

And are then passed to a error handler you made or a default one

#

rn there are two default ones, panic_handler and ignore_handler

#

both do what you'd expect I think haha

#

Or for example I got some inspiration from Lustre

#

But I can't really copy its design because of the fundamental differences and constraints afai

#

And I think for someone that doesn't know functionnal programming at all I did a pretty good job

#

But rn I need to actually learn more of those things before making gaylib good

#

Thank u all for your participation <3

#

See you soon!

gentle harness
#

you need a contributor?

slim granite
#

I mean I wouldn't mind haha

#

Never really collaborated on any of my projects lol

#

So idk how that would go haha

#

And note that this is a complex project that no one will end up using

#

the thing that should actually be done is a raylib-like but in functionnal style

#

which already exists

gentle harness
#

what are you referring to that already exists

#

also no i would use this all the time for many reasons so thats enough of a reason to me

#

i actually was already planning on trying to do gleam bindings for raylib anyways

slim granite
#

Idk their names tho

gentle harness
#

oh lol but thats not gleam nor raylib

slim granite
#

But some are probably already binded to erlang

#

not lots of work to do from there

slim granite
#

Plus

#

Since FFI calls are expensive

gentle harness
#

so theres nothing for me to contribute with?

slim granite
#

I only allow the library to do one per frame

slim granite
gentle harness
#

like if i wanted to help mature the project, is there anything left for me to do?

slim granite
#

So I had to fundamentaly change how raylib works

slim granite
#

Lemme finnish what i'm doing

#

then go see how it's like rn

#

you'll see what i mean

#

it doesn't look like raylib in gleam

#

I could have done it differently

#

like accumulate actions somewhere

#

and then pass them to C and call

#

Which we kinda do rn too

#

but less

gentle harness
#

i mean i'm looking at the main gleam file and it doesnt look that bad

slim granite
#

I'm not saying it does

#

just wait a sec or two

gentle harness
#

ok ๐Ÿ•โ€๐Ÿฆบ

slim granite
#

there

#

implemented what I talked about in my big message

#

the testing.gleam is still similar as before

gentle harness
#

what part did you change?

slim granite
#

Mostly C and a bit of the API

#

Now the C functions return a Result

#

and the errors are passed to window.error which by default is panic_handler

#

before functions returned a badarg

#

which made the BEAM crash with a non very explicit error

#

that was logged to the console yes but before erlang's crap

#

now it doesn't

#

it returns a Result(a, Charlist) (where a is unique to each function)

#

a Charlist is basically and erlang string

#

and then is turned to a gleam String

#

and finally passed to the specified error handler

#

it's not perfect, I plan to return an element from a gleam enum instead

#

and you can fully describe the errors in gleam

#

which is probs better

#

and decide to crash on some and not others

#

rn it's not the case

#

sry i talk in broken-up lines haha

#

idk if you ever worked with NIF so if you have some questions please ask

#

I'm actually getting good at its basics

#

I'll put it in the readme

#

damn I thought you could pin messages in your own posts

gentle harness
#

lowkey waiting for you to be done sending lol idk why

slim granite
#

bottom vibes

#

๐Ÿ’€

#

i'm jk btw

#

dw

gentle harness
#

i initially had a very error-light idea with a context pattern do you wanna see

slim granite
#

what?

#

i don't know what u mean

#

but ig?

#

(i just don't wanna restart making the whole API once again)

gentle harness
#
@external(erlang, "graphics_ffi", "init_context")
fn external_init_context() -> Dynamic

@external(erlang, "graphics_ffi", "flush_commands")
fn external_flush_commands(commands: List(Dynamic)) -> Nil

// command type to represent drawing operations
pub type Command {
  Line(x1: Int, y1: Int, x2: Int, y2: Int)
  Circle(x: Int, y: Int, radius: Int)
  Rectangle(x: Int, y: Int, width: Int, height: Int)
  SetColor(color: String)
}

// drawing context with command buffer
pub type DrawingContext {
  DrawingContext(
    ffi_context: Dynamic,  // Cached FFI context
    commands: List(Command),  // Command buffer
    
    draw_line: fn(Int, Int, Int, Int) -> Nil,
    draw_circle: fn(Int, Int, Int) -> Nil,
    fill_rect: fn(Int, Int, Int, Int) -> Nil,
    set_color: fn(String) -> Nil,
    
    // flush function to execute all commands at once
    flush: fn() -> Nil
  )
}

pub fn new() -> DrawingContext {
  // Initialize FFI context once
  let ffi_context = external_init_context()
 
  let commands = []
  
  // recursive reference for the context
  let ctx = DrawingContext(
    ffi_context: ffi_context,
    commands: commands,
    
    draw_line: fn(_, _, _, _) { Nil },  // Placeholder
    draw_circle: fn(_, _, _) { Nil },   // Placeholder
    fill_rect: fn(_, _, _, _) { Nil },  // Placeholder
    set_color: fn(_) { Nil },           // Placeholder
    flush: fn() { Nil }                 // Placeholder
  )
  
  DrawingContext(
    ..ctx,
    
    draw_line: fn(x1, y1, x2, y2) {
      ctx.commands = [Line(x1, y1, x2, y2), ..ctx.commands]
      Nil
    },
#
draw_circle: fn(x, y, radius) {
      ctx.commands = [Circle(x, y, radius), ..ctx.commands]
      Nil
    },
    
    fill_rect: fn(x, y, width, height) {
      ctx.commands = [Rectangle(x, y, width, height), ..ctx.commands]
      Nil
    },
    
    set_color: fn(color) {
      ctx.commands = [SetColor(color), ..ctx.commands]
      Nil
    },
    
    flush: fn() {
      // Convert commands to the format needed by FFI
      let ffi_commands = convert_commands_for_ffi(ctx.commands)
      
      // Single FFI call to execute all commands
      external_flush_commands(ffi_commands)
      
      // Clear command buffer
      ctx.commands = []
      Nil
    }
  )
}

// convert commands to FFI format
fn convert_commands_for_ffi(commands: List(Command)) -> List(Dynamic) {
  // Implementation would depend on what the FFI expects

}

// Usage example showing reduced FFI calls
pub fn demo_efficient() {
  let ctx = new()
  
  // Queue multiple operations
  ctx.set_color("red")
  ctx.draw_line(0, 0, 100, 100)
  ctx.draw_circle(50, 50, 25)
  ctx.fill_rect(10, 10, 30, 30)
  
  // Single FFI boundary crossing for all operations 
  ctx.flush()
}
#

something like that

#

batch draws as a type then flush

slim granite
#

you might want to put that in a
```rs
```
block

gentle harness
#

something like that ^^^

#

obv keeping most of the current impl in ur repo

#

or not maybe that wont work

#

obv that proto was thought up b4 looking at gaylib

slim granite
#

well i mean

#

that's invalid gleam

#

i don't really understand the idea to be honest-

#

it looks cool

#

but i don't understand

#

like

#

what is ffi_context supposed to be?

#

the rest I kinda get

#

including the flush

gentle harness
#

yeah its more of a pseudo-thing and my b i'm kinda new, stepped straight off the docs

slim granite
#

that's not bad

#

yeah I see

#

first of all

#

ALL gleam variables are immutable

#

so doing ctx.commands = doesn't mean shit

#

x)

#

and ffi_context would probably have an opaque type instead of a Dynamic

#

Dynamics aren't made for what you're trying to achieve

#

I think

#

unless you want it to be editable in gleam

#

usually it represents a dictionnary/tuple or js object depending on the target

#

to be decoded in gleam

#

so it wouldn't be done like that

#

But it's not a bad idea at all

#

however

#

technically gaylib already works in a similar fashion

#

since the draw function is expected to return a list of drawcalls

#

the "flushing" is implicit you could say

slim granite
#

if I wasn't in class i would have suggested to do a call so i can explain properly

gentle harness
#

ah i see (all 3-5 points)

#

imma have to look at your current code and gleam itself

slim granite
#

there is no context exposed tho since it has no purpose for it i think

#

even in raylib the context/window in internal

#

and the informations are exposed through functions

gentle harness
#

yeah my idea stemmed off of how rust kinda does it where you have one type with an inner table of function that you can call all at once so that the drawing state is immutable during the frame and isn't referenced

slim granite
#

yeah but that's not how it works in gleam

#

methods aren't a thing

gentle harness
#

ah

slim granite
#

it's purely functionnal

#

types aren't structures

#

or classes

#

just records

#

and records are just fancy tuples

#

i mean like litteraly

#

it's like tagged tuples if you will

#

where the first element of the tuple is an "atom"

gentle harness
#

well yeah not methods but you can have a function in a record/type

slim granite
#

yes

#

like I did in gaylib

gentle harness
#

yeah

slim granite
#

a window has a bunch of closures/functions

#

that you manually define

gentle harness
#

word

slim granite
#

?

gentle harness
#

like word

#

as in i gotcha

#

understood

slim granite
#

ok ok

#

didn't know that

#

idiom?

#

ig it kinda is

#

whatever

gentle harness
#

oh yeah my bad it's slang/varnacular i guess

#

and hard to convey over text

slim granite
#

yeah i got it dw

slim granite
#

it's slang

gentle harness
#

yeauh

#

also idk if you have any info about it on here but do you have any ideas or intent for the js end?

slim granite
#

gaylib?

#

none

#

It's specifically made for the erlang target

gentle harness
#

ah

#

are you apposed to me trying to see if its possible (leaving the gleam code/syntax the same)

slim granite
#

it probably is

#

but I would find it dumb

gentle harness
#

y

slim granite
#

using C ffi in JS with node or something is not impossible

#

sure

#

you could also do wasm

slim granite
#

since wasm is also a raylib target

#

but that's silly

slim granite
gentle harness
#

can you elaborate

slim granite
#

or C#

#

i don't remember

gentle harness
#

why would it be silly

#

it sounds like a cool experiment to me

ocean pagoda
#

it'd be no more or less silly than writing these C bindings in erlang

slim granite
#

because I hate JS

#

and in contrast, I find the BEAM cool af

gentle harness
slim granite
#

lol

#

I get it

gentle harness
#

so i have something to use instead of js

#

yk?

slim granite
#

yeah i get it

#

use Civet then

#

it's a typescript superset x')

#

it's actually a cool project imo

gentle harness
#

thats still js lol

slim granite
#

yes

#

but with cool functionnal syntax

gentle harness
#

i want the bad stuff out lol not new stuff in

slim granite
#

i mean

#

that will never happend

gentle harness
#

exactly

slim granite
#

JS is a stack of crap

#

and they just keep adding crap

gentle harness
#

thus why im using gleam

slim granite
#

well i mean

#

the JS target is still JS

ocean pagoda
slim granite
#

i wasn't finished

#

with some pieces of good in it

#

that are hidden

#

sadly

gentle harness
#

its like a hazmat suit

slim granite
gentle harness
slim granite
#

i mean yes

#

the callstack

#

it's a stack

gentle harness
#

truuuu

slim granite
#

wait

#

we basically just said that the only thing JS is is a callstack

#

that's wrong

gentle harness
#

i meant that data isnt put on the stack

#

ever

slim granite
#

not really no haha

#

it's not possible with JS

#

everything is dynamic

gentle harness
#

exactly

slim granite
#

which isn't a bad thing in itself

gentle harness
#

yeah but its limitting

slim granite
#

i mean, if the GC was good

gentle harness
#

the gc isnt even the worst thing but yeah

slim granite
#

i mean

#

compare it to Go's or even D's I think

#

-# nuts

gentle harness
#

oh well yeah

#

ironic enough ive seen the worst stuff from the build tooling

#

memory leaks during jitting and whatnot

slim granite
#

ufff

#

true

#

I think JS is a pile of good stuff and of terrible stuff actually

#

but put on old bad stuff

#

it's just sad that it's the main tooling for frontend dev

gentle harness
#

go gc vs js gc isnt even a joke of a contest but i would rather just use rust if im in a position to use go

slim granite
#

i mean depends

#

for instance

#

typescript is being rewritten in Go

gentle harness
#

the best thing about js is its functional syntax more specifically lambdas

#

yeah but bun is in zig

#

which slaps

slim granite
#

since Microsoft is a corporation, time is money, and rewriting it in Go is probs the best choice for them

#

and the fact it has a GC doesn't really matter in their case imo

slim granite
#

and Deno is using rust bindings of V8 I think?

dusky vector
#

iirc the choice was made because go allowed a pretty close 1:1 representation of the existing TS logic

slim granite
#

ik

#

so it was fast to change

gentle harness
#

i dont get why wouldnt ms just use c# if dotnet is so good according to them

slim granite
#

they had a script do most of the job

slim granite
#

I like C# honestly it's a good language for some stuff imo

#

but it's not in a good state

gentle harness
#

i just dont like dotnet

dusky vector
#

i prefer the java language but the dotnet tooling ๐Ÿ‘

slim granite
#

yes same

#

what

#

i mean

gentle harness
dusky vector
slim granite
#

maven and gradle are

gentle harness
slim granite
#

i guess dotnet is better in some aspects

dusky vector
#

terrible

gentle harness
#

i need a lang to come with tooling tbh

dusky vector
#

gradle is the worst build system i've ever had the displeasure of using

slim granite
#

well i mean groovy is a terrible language lol

gentle harness
#

gradle is fine to me honestly ive had better experiences with it than dotnet

dusky vector
#

i use the kotlin dsl

gentle harness
slim granite
#

that's why i do my gradle configs in kotlin

#

oh

sick thicket
#

No language bashing please!

slim granite
#

lol

gentle harness
slim granite
#

yeah sorry-

gentle harness
#

/j

slim granite
#

I don't mean it like that tho

#

I get why it exist

#

there is a cool part I get it

#

but if it's basically unsed except for gradle there are reasons i'd say

gentle harness
slim granite
#

i think it is yes

#

i wonder

gentle harness
#

lua is my favorite interpretted lang ๐ŸŒ

slim granite
#

i get why

#

is it possile to do a minecraft mod in groovy

#

mmh

gentle harness
#

i hope not

slim granite
#

i guess with lots of work you might be able to do some parts in it

gentle harness
#

yeah...

slim granite
#

Tho mixins would need to be in Java like Kotlin mods

#

I know quilt has part of it's std also made / wrapped in kotlin if u use it

#

btw

#

let's stop

#

this ain't about gaylib-

gentle harness
#

yeah all i know is multi-paradigm >>>>>

#

ok im done

slim granite
#

alright added a way to configure the window

pub fn main() {
  let window =
    gl.basic_window(
      width: 800,
      height: 600,
      title: "Gaylib Test",
      default: State(gl.Color(255, 0, 0, 255), 0.0),
      update:,
      draw:,
    )
    // NEW! gl.configure TM /j
    |> gl.configure(
      gl.default_config()
      |> gl.config_vsync_hint()
      |> gl.config_undecorated(),
    )

  gl.start(window:, update:, draw:)
}
#

now the config needs to be used in C

#

done

#
@external(erlang, "gaylib_ffi", "init_window")
fn init_window(
  width: Int,
  height: Int,
  title: Charlist,
  fps: Int,
  config_flags: Int,
) -> Result(Nil, Charlist)
``` now `init_window` takes `config_flags` as an Int
#

and said int is made from the config: Config field of the Window using this big function

/// Converts the boolean based `Config` to raylib window bitwise orred flags.
pub fn config_to_flags(config: Config) -> Int {
  case config.vsync_hint {
    True -> 0x00000040
    False -> 0
  }
  |> int.bitwise_or(case config.fullscreen_mode {
    True -> 0x00000002
    False -> 0
  })
  |> int.bitwise_or(case config.window_resizable {
    True -> 0x00000004
    False -> 0
  })
  |> int.bitwise_or(case config.window_undecorated {
    True -> 0x00000008
    False -> 0
  })
  |> int.bitwise_or(case config.window_hidden {
    True -> 0x00000080
    False -> 0
  })
  |> int.bitwise_or(case config.window_minimized {
    True -> 0x00000200
    False -> 0
  })
  |> int.bitwise_or(case config.window_maximized {
    True -> 0x00000400
    False -> 0
  })
  |> int.bitwise_or(case config.window_unfocused {
    True -> 0x00000800
    False -> 0
  })
  |> int.bitwise_or(case config.window_topmost {
    True -> 0x00001000
    False -> 0
  })
  |> int.bitwise_or(case config.window_always_run {
    True -> 0x00000100
    False -> 0
  })
  |> int.bitwise_or(case config.window_transparent {
    True -> 0x00000010
    False -> 0
  })
  |> int.bitwise_or(case config.window_highdpi {
    True -> 0x00002000
    False -> 0
  })
  |> int.bitwise_or(case config.window_mouse_passthrough {
    True -> 0x00004000
    False -> 0
  })
  |> int.bitwise_or(case config.borderless_windowed_mode {
    True -> 0x00008000
    False -> 0
  })
  |> int.bitwise_or(case config.msaa_4x_hint {
    True -> 0x00000020
    False -> 0
  })
  |> int.bitwise_or(case config.interlaced_hint {
    True -> 0x00010000
    False -> 0
  })
}
#

since it's called once I don't really care that it does lots of FFI calls

ocean pagoda
#

what stops someone calling it with 123456789 as an argument instead of using this function?

slim granite
#

i mean it's private

#

it's not supposed to be called by the user

#

but nothing

#

just like in C

#

it's not an excuse btw

#

i just don't know how to prevent the user from doing it

#

like I could make a private type with an internal int

#

but since the init_window function is private I don't think it matters?

#

there is no way to pass in the int flags manually

slim granite
#

if it's not good enough ig i'd like to know how to make it enough x)

#

?

sick thicket
#

Oh yeah then it makes sense! Then the config_to_flags function should be private too, right?

slim granite
#

oh it is

#

i just tested it so made it public

#

sorry

#

forgot to mention that

#

oh wait

#

no nvm

#

it can't

#

since Config is a public type

#

and it needs to be public too since it's used in other APIs including the Window record

lucid prairie
#

Why don't you make init_window accept Config instead of Int?

slim granite
#

because i'm lazy to convert the huge record that is Config to ints in C

#

ik it would be better

#

i'll probably do it at some point

lucid prairie
#

You can still do the conversion in Gleam

#

Just do it privately so users can't make invalid config

slim granite
#

it's done privately?

#

init_window is not accessible

lucid prairie
#

Oh I see

slim granite
#

you can't pass something invalid to it

lucid prairie
#

Ok nvm I'm getting confused then

#

Ok that's fine yeah

slim granite
#

mhm

slim granite
#

we can call now @gentle harness / go to general vc i'm free
if you want me to explain the codebase

#

probs better

slim granite
#

if you need it that is

#

Oh I just understood something

#

Before returning an Error() on errors, I was returning something called a "badarg" since it's what's used in erl_nif's example

#

and that's an exception

#

lol

#

I forgot that was a thing in erlang

#

new commit dabs

slim granite
#

kinda haha

#

in 1 hour it's good tho

#

but I can guide you textually too if you want

slim granite
gentle harness
#

nah i can wait, working on sum rn anyways

#

you can give info tho i'm just not actively looking

slim granite
#

well i mean

#

i'm ready now

gentle harness
#

oh damn

slim granite
#

if you want/can

gentle harness
#

yeah sure

#

which chan

#

?

slim granite
#

Sorry for the lack of updates i've been pretty tired lately ':/

proper osprey
#

No need to apologise :)

ashen arrow
#

that's one hell of a name

#

i love it

slim granite
#

hehe

#

it started as a typo

#

lol

still saffron
ashen arrow
slim granite
#

lol

slim granite
#

tho it's really the case here

#

it should have been glaylib or raygleam (that also had a typo in the poll, it was typed rayglib)

#

but raygleam won

slim granite
#

and i changed Jared (the logo) to have "gaylib" typed on it instead of "raygleam"

#

looked cool

#

with the gay pride plag

#

so I kept it

slim granite
#

damn

#

i forgot this was a thing

slim granite
#

alright

#

I think it's time to continue this

#

well not right now

#

but soon

#

:p

wraith badger
#

Wow peak i love raylib maybe I should learn gleam someday

#

ehhh prob not I like c++

worldly mango
#

did u just think out loud in chat ๐Ÿ˜…

scenic mulch
#

What license is this ?

#

I'm interested in some of the code for erlang (not gleam)

#

i do love me some gleam though.. but not in this case

slim granite
#

c++ and gleam are

#
  1. different paradigms
#
  1. different use cases
#
  1. functionnaly different (gleam is not a compilable language, it runs in a VM, akin to Java in the JVM)
#

it's like comparing pizza to a hammer

slim granite
wraith badger
#

gleam does look cool tho

#

So maybe somedayโœŒ๏ธ

slim granite
#

:3

slim granite
#

refactored the shitty C code today lol

slim granite
#

there!!!

#

it's all in here now

#

all clearer

#

also some new TODOs

#

1 for better error handling

#

and the other for signal handling

#

cuz I noticed that if the NIF raised a signal

#

the beam just sorta stops

#

and exits with exit code 0

#

even with a segfault

#

(which is not so great lol)

slim granite
#

now that I split the C in multiple parts

#

should I do the same with gaylib.gleam?

#

like putting all the direct bindings (only types afaik) into gaylib/bindings or gaylib/types

#

and stuff like that

#

what do you think?

lucid prairie
#

That's generally considered an antipattern in Gleam. You should group your modules by behaviour, not type of definition

slim granite
#

ah

#

but it's a bindings library so there is no direct behaviour-

#

the behaviour is in C

#

i just find it kind of a mess to navigate with absolutely everything in the same place

lucid prairie
#

The functions still have behaviour when you call them though, regardless of implementation language

slim granite
#

it's just that there are a ton of types-

lucid prairie
#

I'm not super familiar with the Raylib API, but off the top of my head you could split code for 2d drawing, 3d drawing, audio, etc

slim granite
#

linear algebra too

#

or what raylib calls raymath

#

but it's mostly linear algebra

#

makes sense makes sense

#

and I can't really do as you say

#

since i'm not doing function to function bindings

#

Like, for instance

#

drawing requires you to create a "Drawcall" from one of its constructors (like Rectangle, Background, etc...)

#

and it's a single type

#

i can't just split it can I?

lucid prairie
#

Those sound like pretty tightly coupled pieces of a code, so you wouldn't want to split those

slim granite
#

yeah I see

lucid prairie
#

Really you would split it if you have several distinct sections of the library that don't interact and can each function on their own

slim granite
#

well appart linear algebra everything needs each other directly

lucid prairie
#

For example, looking at the library, I could imagine you splitting it into a config module, a maths module and then the main module for actually drawing to the screen

slim granite
#

why config?

#

it's useless on its own?

lucid prairie
#

It's a distinct piece of code which can exist independently of the rest of the code

slim granite
#

no it can't?

#

it needs types from the main gaylib module?

#

like Window

#

at least part of it

lucid prairie
#

Just looks like booleans to me

slim granite
#

ah that yes

#

but then you have the configure function that needs it

lucid prairie
#

Well yes, that would be in the main module

slim granite
#

i'm not going to make a module for just a type?

lucid prairie
#

But all these functions

slim granite
#

i guess

lucid prairie
#

Or you keep it as one module

#

You were the one asking for ideas on how to split it, so I gave you some

slim granite
#

yes yes yes

#

sorry

#

i'm just not sure i follow

#

but okay

#

there

#

did you mean smth like that?

lucid prairie
#

Yeah something like that

#

You can play around with it to see if you think it's an improvement over the old api

slim granite
#

i think it is but also not cuz well

#

if you look in testing.gleam

#

i found it clearer to directly rename them

slate crest
#

guys, I think I can't use this library, I'm too straight here... no wait, yea, I can use it

slim granite
#

dw only the logo is gay

slim granite
#

ik it's funny but

#

gl does really sound like other.... open source library

#

open

slate crest
#

but the lib looks cool, gonna test it more later

slim granite
#

the "gay" is using the pride flag

slim granite
#

only two "draw calls" are implemented

#

clearing the background and drawing the FPS count

#

you can use keydown "events" too

#

and close the window

slate crest
#

hmmmm, time to see if I can make a box move with only a background

#

technically, if I have 2 apps running

#

hmmmmmmmmm

#

time to be stupid

slim granite
#

lol

slate crest
#

sry, it's getting late here, it's perfect time for stupid ideas

slim granite
#

dw

#

have fun

slim granite
# slim granite
poll_question_text

Should we split the gaylib module into submodules

victor_answer_votes

3

total_votes

4

victor_answer_id

2

victor_answer_text

No

victor_answer_emoji_id

1134926343235194933

victor_answer_emoji_name

squirtle

slim granite
#

well

#

i think i'm going to need to uncommit the commit

lucid prairie
#

That's why you usually want to make a branch for experimental changes

slim granite
#

im the only one to work the project

#

who cares

#

there

#

never happened

slate crest
#

:d

slim granite
scenic mulch
#

It might be late, but if you do split it out, at least 1 nif plz.

#

ty

slim granite
#

only the C is split into multiple C files

#

cuz it was a mess to manage

#

just did some refactoring

#

i am planning on finally porting more draw functions

#

but to do that

#

i decided to split drawcalls handling into its own function

slim granite
#

@scenic mulch when did u plan to contribute btw?

scenic mulch
#

Oh. Gotta finish this tui framework. Feel free to go ahead and do your own thing.

#

I was hoping over November

slim granite
#

okayyy