Making leaps to better data serialization

This commit is contained in:
Chris Bell 2025-02-26 23:21:08 -06:00
parent 86c0b7ca6a
commit c6c8864d67
4 changed files with 93 additions and 75 deletions

View File

@ -1,8 +1,8 @@
package game package game
Vec2i :: struct { Vec2i :: struct {
x: int, x: i32,
y: int, y: i32,
} }
vec2i_to_vec2 :: proc(v2i:Vec2i) -> [2]f32 { vec2i_to_vec2 :: proc(v2i:Vec2i) -> [2]f32 {
@ -10,43 +10,17 @@ vec2i_to_vec2 :: proc(v2i:Vec2i) -> [2]f32 {
} }
vec2_to_vec2i :: proc(v2:[2]f32) -> Vec2i { vec2_to_vec2i :: proc(v2:[2]f32) -> Vec2i {
return {int(v2.x), int(v2.y)} return {i32(v2.x), i32(v2.y)}
} }
serialize_vec2i :: proc(v:Vec2i) -> [8]byte { to_bytes :: proc(v: $T) -> [size_of(T)]u8 {
data: [8]byte val := v
encoded_bytes := (^[size_of(T)]u8)(&val)
x := serialize_int(v.x) return encoded_bytes^
y := serialize_int(v.y)
for i in 0..<4 {
data[i] = x[i]
}
for i in 0..<4 {
data[4 + i] = y[i]
}
return data
} }
deserialize_vec2i :: proc(data:[]byte) -> Vec2i { from_bytes :: proc($T:typeid, data: [size_of(T)]u8) -> T {
x := deserialize_int(data[0:4]) bytes := data
y := deserialize_int(data[4:8]) decoded_value := (^T)(&bytes)^
return Vec2i{x,y} return decoded_value
}
serialize_int :: proc(v:int) -> [4]byte {
data : [4]byte
data[0] = byte(v)
data[1] = byte(v >> 8)
data[2] = byte(v >> 16)
data[3] = byte(v >> 24)
return data
}
deserialize_int :: proc(data:[]byte) -> int {
return int(data[0]) | int(data[1]) << 8 | int(data[2]) << 16 | int(data[3]) << 24
} }

BIN
tests/test Executable file

Binary file not shown.

View File

@ -1,47 +1,91 @@
package test package test
import game "../game"
import "core:fmt" import "core:fmt"
import rl "vendor:raylib" import "core:os"
import "core:encoding/endian" import "core:slice"
my_enum :: enum {
val1,val2,
}
my_struct :: struct {
me: my_enum,
num: i32,
v: Vec2i
}
main :: proc() { main :: proc() {
final_val:my_struct
buf : [128]u8 make_struct()
my_int : i32 = -32
endian.put_i32(buf[:], .Little, my_int) data := load_file("test1")
if data != nil {
if len(data) == size_of(my_struct) {
static_bytes: [size_of(my_struct)]u8
copy(static_bytes[:], data)
final_val = from_bytes(my_struct, static_bytes)
}
}
fmt.printfln("u8 buffer: %v", buf) fmt.printfln("Decoded Val: %v", final_val)
decoded_int, err := endian.get_i32(buf[:], .Little)
fmt.printfln("Pre-encoding: %v | Decoded int: %v", my_int, decoded_int)
// nothing := game.Tile {
// type = .NOTHING,
// color = rl.RED,
// tilemap_pos = {3,3},
// resource = .NOTHING,
// interaction = .NOTHING,
// }
// ts := game.serialize_tile(nothing)
// fmt.printfln("Expecting size: %v, Got size: %v", size_of(game.Tile), len(ts))
// fmt.printfln("Pre-serialized Tile: %v", nothing)
// dst := game.deserialize_tile(ts)
// fmt.printfln("Post-serialized tile: %v", dst)
// y : int
// chunk := game.Chunk {
// position = {0,1}
// }
// for x in 0..<len(chunk.tiles) {
// for y in 0..<len(chunk.tiles) {
// chunk.tiles[x][y] = nothing
// }
// }
} }
make_struct :: proc() {
ms := my_struct {
me = .val1,
num = 345,
v = {45,75}
}
fmt.printfln("Initial value: %v", ms)
bytes := to_bytes(ms)
fmt.printfln("Bytes: %v", bytes)
save_file("test1", bytes[:])
}
load_file :: proc(path:string) -> []u8 {
if !os.is_file(path) {
fmt.printfln("File not found")
return nil
}
data, err := os.read_entire_file_from_filename_or_err(path)
if err != nil {
fmt.printfln("File read error: %v", err)
return nil
}
fmt.printfln("Loading file: %v", path)
return data
}
save_file :: proc(path:string, data:[]u8) {
err := os.write_entire_file_or_err(path, data)
if err != nil {
fmt.printfln("File write error: %v", err)
return
}
fmt.printfln("Wrote file: %v", path)
}
Vec2i :: struct {
x: i32,
y: i32,
}
to_bytes :: proc(v: $T) -> [size_of(T)]u8 {
val := v
encoded_bytes := (^[size_of(T)]u8)(&val)
return encoded_bytes^
}
from_bytes :: proc($T:typeid, data: [size_of(T)]u8) -> T {
bytes := data
decoded_value := (^T)(&bytes)^
return decoded_value
}

BIN
tests/test1 Normal file

Binary file not shown.