Claude Sonnet 3.7 is the first #GenAI I tried out that actually produced usable code. The code is not pretty but it was the first time I was impressed by an AI system being able to produce non-trivial code and being able to adjust it to feedback.
I should stop using #python for one off scripts to convert data. The #rust ecosystem has a similar maturity. Building such scripts takes roughly the same time in both languages, but the rust system will finish the job order of magnitudes faster.
When your rust program feels slow you probably forget --release.
Spent a lot of time trying to streamline the guest AI code. This is something I still can wrap my head around entirely, partially due to #rust, mainly as this is something I never worked on before.
Corridors and doors are now rendered in front of rooms. Rooms are only shown if someone is in them.
Slow progress in the last couple of sessions. I've started to implement employees. Employees work at rooms/stations whenever a guest wants to interact with them (e.g. booking a room). I'm not yet 100% happy with the implementation (blaming my #rust skills).
Additionally implemented a hunger+restaurant prototype.
For my DungeonPlanner project I wanted to use custom icons for the tool buttons. Unfortunately the documentation for this is rather slim. As an additional constraint, the image data should be embedded in the binary as I like to compile and ship a single binary file (as long as this is possible).
The nearest approach I could find was to create buttons with downloaded images. The snippet is for GTK3 so it had to be adjusted for GTK4, but it contained the right function names to know what to search for :).
This is the final code I ended up with:
let button = Button::new();
let bytes = include_bytes!("../../assets/icons/add_chamber.png");
let g_bytes = glib::Bytes::from(&bytes.to_vec());
let stream = MemoryInputStream::from_bytes(&g_bytes);
let pixbuf = Pixbuf::from_stream(&stream, Cancellable::NONE).unwrap();
let texture = Texture::for_pixbuf(&pixbuf);
let image = Image::from_paintable(Some(&texture));
button.set_child(Some(&image));
We start by creating a button. Instead of using the ButtonBuilder as you would normally do, I'm just creating an "empty" button. It should be possible to still use the builder, as we are just replacing the child content at the end.
let button = Button::new();
Next we need to load our image data. As I want my images to be embedded in the binary I use the include_bytes! macro. The raw bytes are then turned into a glib:Bytes struct and finally into a MemoryInputStream. The stream is needed to parse the image data.
let bytes = include_bytes!("../../assets/icons/add_chamber.png");
let g_bytes = glib::Bytes::from(&bytes.to_vec());
let stream = MemoryInputStream::from_bytes(&g_bytes);
The next goal is to create an Image object containing our embedded image. With GTK 4.6 we could still use Image::from_pixbuf but this will be deprecated in GTK 4.12. Instead we have to do an extra step and create a Texture and use Image::from_paintable. The texture can simply be created from a Pixbuf, which is created by using the Pixbuf::from_stream function
let pixbuf = Pixbuf::from_stream(&stream, Cancellable::NONE).unwrap();
let texture = Texture::for_pixbuf(&pixbuf);
let image = Image::from_paintable(Some(&texture));
Finally we can set the child of our button to the image and our icon button is done. The same approach also works for ToggleButton.
I've fixed a crash in #DungeonPlanner which happened whenever a Dungeon with an empty chamber was exported. Also updated the dependencies while I was at it.