chunqian / go-raylib

go-raylib is a simple and easy-to-use library to enjoy videogames programming
zlib License
44 stars 3 forks source link

Convert `const unsigned char` to `[]byte`, not `string` #9

Closed makew0rld closed 3 years ago

makew0rld commented 3 years ago

Looking at the raylib cheatsheet, you can see that in many places const char is used for strings, while const unsigned char is used for bytes. But this package converts both of those to Go's string type. This is a problem, because if I load some bytes from a file or memory (maybe to load an image), I need to convert those bytes first with string(bytes). This copies all of the bytes before giving them to the library, because strings are immutable. Copying the bytes is an expensive and useless operation here.

There are ways around the copying, but could you just change the binding, so it converts const unsigned char to []byte? Thanks!

Example function that does this:

Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize);
chunqian commented 3 years ago

OK Let me see how to change I need to review the code in c-for-go project

chunqian commented 3 years ago

@makeworld-the-better-one The slice memory model in go is not the same as the array in c Slice cannot be passed directly into c You can look at func unpackSByte() in cgo_helpers.go

chunqian commented 3 years ago

I have tested Basically, there is no difference in performance with raylib c version But the memory model is different, so there will be inevitably some memory conversions with cgo

makew0rld commented 3 years ago

Ah ok, that's too bad.

There definitely is a performance drop though, because string(bytes) copies all the bytes. For now I will use the function I linked to prevent that copying:

func ByteSlice2String(bs []byte) string {
    return *(*string)(unsafe.Pointer(&bs))
}
chunqian commented 3 years ago

@makeworld-the-better-one raylib-go just not dealing with the memory model So I started a new project The focus is to solve this memory model conversion problem

texture := rl.LoadTexture("../models/resources/cubicmap_atlas.png")
model.Materialser(0).Mapser(rl.MAP_DIFFUSE).Texture = texture

Here the Materialsser Mapser is the manager

makew0rld commented 3 years ago

Ok, thanks.

Another way to solve this might be to create your own type like type RlBytes string, and then provide the function above as a way to convert to that type. And then turn all const unsigned char C code into the RlBytes type. But anyway, I can work around this.

chunqian commented 3 years ago

@makeworld-the-better-one Slice in plain type converts to c without problems Only Slice in struct type converts to c will have go pointer problem I have updated go-raylib

makew0rld commented 3 years ago

Oh great! I can confirm 9be3f7a95814 works with passing []bytes. Thanks for adding this!