code_generation

Overview

This shows some basic code generation / meta programming.

The code generation is done by running a separate program that generates some Odin code.

Generate images.odin by running:

odin run generate_image_info

The following will build the program that actually uses images.odin:

odin run .

It will print:

Long_Cat is 9 x 46 pixels and 183 bytes large

Round_Cat is 20 x 24 pixels and 317 bytes large
Round_Cat has width > 15, so we loaded it!
The loaded PNG image is indeed 20 pixels wide!

Tuna is 24 x 20 pixels and 318 bytes large
Tuna has width > 15, so we loaded it!
The loaded PNG image is indeed 24 pixels wide!

Code

main.odin ¶
48 linesSource

1package image_viewer
2
3import "core:image"
4import "core:image/png"
5
6// Avoids 'unused import' error: "core:image/png" needs to be imported in order
7// to make `img.load_from_bytes` understand PNG format.
8_ :: png
9
10import "core:fmt"
11
12/*
13This program prints:
14
15	Long_Cat is 9 x 46 pixels and 183 bytes large
16	
17	Round_Cat is 20 x 24 pixels and 317 bytes large
18	Round_Cat has width > 15 we loaded it!
19	It is indeed 20 pixels wide!
20	
21	Tuna is 24 x 20 pixels and 318 bytes large
22	Tuna has width > 15 we loaded it!
23	It is indeed 24 pixels wide!
24
25Note how it knows width and height before it loads the file. That was written
26into `images.odin` by the code generation program in the `generate_image_info`
27folder. It also knows the file size: `img.data` contains the data (i.e. the file
28contents) for that image. That data is put into the executable at compile time
29using the built-in `#load` procedure. The path of the image send into `#load`
30is written by the code generation program.
31*/
32main :: proc() {
33	for &img, name in images {
34		fmt.printfln("%v is %v x %v pixels and %v bytes large", name, img.width, img.height, len(img.data))
35
36		// Make decisions based pre-computed data before actually loading the image
37		if img.width > 15 {
38			loaded_img, loaded_img_err := image.load_from_bytes(img.data)
39
40			if loaded_img_err == nil {
41				fmt.printfln("%v has width > 15, so we loaded it!", name)
42				fmt.printfln("The loaded PNG image is indeed %v pixels wide!", loaded_img.width)
43			}
44		}
45
46		fmt.println()
47	}
48}

images.odin ¶
21 linesSource

1// This file is generated. Re-generate it by running:
2//	odin run generate_image_info
3package image_viewer
4
5Image :: struct {
6	width: int,
7	height: int,
8	data: []u8,
9}
10
11Image_Name :: enum {
12	Long_Cat,
13	Round_Cat,
14	Tuna,
15}
16
17images := [Image_Name]Image {
18	.Long_Cat = { data = #load("images/long_cat.png"), width = 9, height = 46 },
19	.Round_Cat = { data = #load("images/round_cat.png"), width = 20, height = 24 },
20	.Tuna = { data = #load("images/tuna.png"), width = 24, height = 20 },
21}

Assets 3

Declarations Used 3