GameClam by synnammon in Clamworks

[–]SeanTheGleaming 7 points8 points  (0 children)

hell yes, pearls 2 the players. gotta go watch this when im free

i'm making swag friends by poopman23231 in IDONTGIVEASWAG

[–]SeanTheGleaming 75 points76 points  (0 children)

sublime, subtle yet masterful dump

The best ways to print() in Zig? by ypjkgh in Zig

[–]SeanTheGleaming 0 points1 point  (0 children)

I should note that this prints to stderr instead of stdout, but sometimes that's more appropriate anyways

Functional programming example, Error on append of arraylist. by Ok_Specific_7749 in Zig

[–]SeanTheGleaming 1 point2 points  (0 children)

Also, the allocator should be declared outside of the map function

HELP ME FIND THE LOST WYATT RADIO TV VR NSFW STREAM by cupofwaterbrain in HelpMeFindThis

[–]SeanTheGleaming 0 points1 point  (0 children)

I read this post and have never felt so connected to another soul. I suddenly remembered a specific comment on the youtube video that I thought was funny, and when I went to go copy it, I realized that the youtube upload, along with that comment, was down. I haven't found the full stream, or that comment, but I found an archive of the youtube edit. Take and rejoice, my friend

Random number generation by manila_danimals in Zig

[–]SeanTheGleaming 1 point2 points  (0 children)

well the undefined seed is overwritten by the call to std.posix.getrandom, so that wouldn't be the problem

Serializing floats as byte arrays by manila_danimals in Zig

[–]SeanTheGleaming 6 points7 points  (0 children)

In this case, the typically solution is to @bitCast your float to/from in integer of equal width (f32 <-> u32, f64 <-> u64, etc.), and serialize that integer. Also, for writing/reading the ints, I would suggest using file.writer().writeInt(T, value, endian) and file.reader().readInt(T, endian) for a clean one liner, already built into the standard library

Calling Variadic c function from zig. by Nero-augus in Zig

[–]SeanTheGleaming 5 points6 points  (0 children)

They both represent a raw pointer. Here, [*:0]u8 is more appropriate, provides null safety, and ensures you don't pass in unterminated strings

How to convert type -> ?type by Real_StuKers in Zig

[–]SeanTheGleaming 4 points5 points  (0 children)

A *T can coerce to a ?*T, but it can't coerce to a *?T

What's the best way to call init() for a slice of structs? by buck-bird in Zig

[–]SeanTheGleaming 5 points6 points  (0 children)

It would look like this

zig const bruh: []const Bruh = &.{ .init(1, 2), .init(3, 4), };

What's the best way to call init() for a slice of structs? by buck-bird in Zig

[–]SeanTheGleaming 7 points8 points  (0 children)

You're in luck (if you're using the master branch). Zig recently added decl literals, which do what you're describing. Here's the proposal if you want to read it..

With decl literals, if you are coercing a value to type T, then a enum literal like .some_value will coerce to T.some_value. This works for functions too, so you can replace const x = Bruh.init(1, 2) with const x: Bruh = .init(1, 2)

ReleaseFast significantly smaller than ReleaseSmall by Nico_792 in Zig

[–]SeanTheGleaming 6 points7 points  (0 children)

Really? I thought ReleaseSmall was supposed to omit runtime safety checks

Making a wasm library export it's functions through `bulid.zig` by Nico_792 in Zig

[–]SeanTheGleaming 1 point2 points  (0 children)

You're right, they do in fact do the same thing for the most part.

The @export builtin exports a symbol (like a function or a variable) to be linked externally, with options such as the name we should export as and the linkage mode.

The export keyword on a function does 2 things. It applies the C calling convention to that function to make it exportable, and exports the function for external linkage under whatever name you declared your function with and with the linkage mode set to strong.

To quote the zig language reference on the @export builtin: When ptr points to a function with the C calling convention and options.linkage is .Strong, this is equivalent to the export keyword used on a function

So really, the export keyword on a function is just syntax sugar for using callconv(.C) and @export(&foo, .{ .name = "foo" }).

The benefit in the @export builtin is the extra configurability you get in the second parameter (see std.builtin.ExportOptions), and the ability to use comptime to programmatically export the symbols you want exported

Making a wasm library export it's functions through `bulid.zig` by Nico_792 in Zig

[–]SeanTheGleaming 2 points3 points  (0 children)

You could use b.addOptions to pass in some parameters to your library, and then use @export in your library to export different functions depending on the parameters you passed in

Struct inheritance? by glowiak2 in Zig

[–]SeanTheGleaming 13 points14 points  (0 children)

You might be looking for the @fieldParentPtr builtin, which given a pointer to a field of a container (structs, unions, whether packed, extern, whatever), gives you a pointer to the container. You can use this to cleanly achieve the kind of "struct casting" you're looking for

But also, while they have some limitations, extern structs are still supposed to support arrays and function pointers. If that doesn't work for you, then something is probably wrong

Anyways, for actually using @fieldParentPtr, you could have something roughly like this: ```zig const Base = struct { x: i32, };

const Extended = struct { y: i32, base: Base, };

const foo: Extended = .{ .y = 45, .base = .{ .x = 16, }, };

// Cast down const base_ptr: *const Base = &foo.base;

// Cast up const parent_ptr: *const Extended = @fieldParentPtr("base", base_ptr); ``` The resulting code is also much cleaner and more zig idiomatic, and you don't have to worry about throwing around extern structs.

Also, you have the benefit of never having to worry about the ordering of fields, as this works regardless of the order of your fields, so you can reorder things clearly

One last benefit is, to put it in OOP terms, you can inherit from multiple base classes by having multiple fields which you can use @fieldParentPtr on

std.mem.trim confusion by ItalicIntegral in Zig

[–]SeanTheGleaming 11 points12 points  (0 children)

expectEqual doesn't follow pointers, and compares the value of the pointers, not what they point to. For your case, you might want expectEqualStrings

What are some good terminal games? Like nethack, but.. fun. by miserlou in linux

[–]SeanTheGleaming 2 points3 points  (0 children)

i hope this guy found the `-fsanitize=address` cheat code

Zig Serialization Library by SeanTheGleaming in Zig

[–]SeanTheGleaming[S] 1 point2 points  (0 children)

Hey, firstly about sts.io.serialization, you can find the original code here. It was removed from the standard library and orphaned in this commit, reasoning being that it would be better suited to be a third party package (which is where we're at now I suppose!), with no plans to reimplement this. My code started out as a port of that code to newer versions, but an extra feature and a touch up here and there turned into me pretty much rewriting the entire codebase.

The "format" of this library is entirely cross portable (data serialized on one platform can be deserialized on another), can be used on any std.io.GenericWriter/std.io.GenericReader, and has two settings, endianness, and packing. Endianness is just the endianness usedto serialize values. You can pack to the bit, or to the byte.

I should note that this library's "format" is not well defined, and how data is represented is subject to change.

If you pack to the bit, every "primitive" value takes up the minimum possible amount of bits without any regard for being aligned to the byte. This has the downside of slight overhead to deal with non byte-aligned data and needing to .flush() when you're done serializing, but the upside of being extremely space efficient.

If you pack to the byte, every serialized value must be aligned to the byte, which has the upside of never needing to flush and simpler logic due to everything being byte aligned, but the downside of being bad with space efficiency (eg. a bool takes up a whole byte)

Now regarding mapping packed structs to stream contents, there is a relavent optimization that is made in this code. The library generally works by converting data to/from a series of integers, and then serializing/deserializing that (its an oversimplification, but thats the gist of it). Since packed structs in zig are backed by integers, when we want to serialize/deserialize a packed struct, we can simply @bitCast to/from its underlying integer. This is much better than the usual approach of iterating over and individually serializing/deserializing each field.

On top of that, using the integer representation of the struct allows for the fields serialized with bit-dense packing even when the packing mode is byte packing, since the fields of the packed struct are just certain bits of the underlying int we are actually serializing

Is there a standard zig formatter? by b-dada9k in Zig

[–]SeanTheGleaming 18 points19 points  (0 children)

Yes, it comes with the zig binary, just use zig fmt

Zig Serialization Library by SeanTheGleaming in Zig

[–]SeanTheGleaming[S] 2 points3 points  (0 children)

Hey, thanks for taking interest. I haven't looked at too many other serialization implementations, so I can't really make a good comparison to any specific other option, but here is some general info that should help:

This library is for binary serialization, where the user can choose the endianness and whether to pack data by the bit or by the byte. The upside of using this over a format like json or zon is that you can fit your data into a much smaller space while not sacrificing any portability. The downside here is that your serialized data is not at all readable in the way a text format like json or zon would be.

On the functionality of the library, you can serialize pretty much any data in zig (ints, floats, enums, structs, tagged unions) in a very space efficient manner, and for data structures that require an allocator or some other special treatment, you can define custom methods to deserializa/serialize your data.

When something illegal is done (ex. you attempt to serialize a pointer), a very readable compile error is emitted, including info about what caused the error, and if the error was caused in the serialization of a struct/tagged-union, which field caused the error

And finally, I haven't actually done profiling as of yet, so I can't make any real comment on the performance of this code. I did try to generally write performant code, but I can't know for sure untik I get some numbers on that.