add debug memory monitoring

This commit is contained in:
Hayden Johnson 2026-02-19 20:38:25 -08:00
parent 7562fd3043
commit 0adeba4daa
2 changed files with 59 additions and 7 deletions

View file

@ -2,6 +2,7 @@
----------------
Phase 10 Tracker
----------------
Author: Hayden Johnson
This program helps the user keep track of a game of Phase 10 as it is being
played. It will keep track of players and their scores over the course of the
@ -14,9 +15,36 @@
*/
package phase10
import "core:os"
import "core:fmt"
import "core:mem"
main :: proc() {
// Memory tracking when building in debug mode
when ODIN_DEBUG {
track: mem.Tracking_Allocator
mem.tracking_allocator_init(&track, context.allocator)
context.allocator = mem.tracking_allocator(&track)
defer {
if len(track.allocation_map) > 0 {
fmt.eprintf(
"=== %v allocations not freed: ===\n",
len(track.allocation_map)
)
for _, entry in track.allocation_map {
fmt.eprintf("- %v bytes @ %v\n", entry.size, entry.location)
}
}
mem.tracking_allocator_destroy(&track)
}
}
// TODO don't just test this, actually read the fields into a game struct
if len(os.args) > 1 {
importGame(nil, os.args[1])
}
// Prompt for names
buf: [2048]byte
names := getNames(buf[:])
@ -40,13 +68,11 @@ main :: proc() {
winner = checkWinner(&game)
}
// Print winner
// Print winner and export game
fmt.printfln(
"%v wins! They had %v points!",
game.names[winner],
getScore(&game, winner)
)
exportGame(&game, "game.csv")
}

View file

@ -137,7 +137,11 @@ getNames :: proc(backingBuffer: []byte) -> []string {
// export a game as a csv
exportGame :: proc(game: ^Game, filename: string) {
// Open handle to file
handle, err := os.open(filename, flags = os.O_CREATE | os.O_WRONLY | os.O_TRUNC, mode = 0o666)
handle, err := os.open(
filename,
flags = os.O_CREATE | os.O_WRONLY | os.O_TRUNC,
mode = 0o644
)
if err != nil {
fmt.eprintln("Could not open file:", filename)
return
@ -152,6 +156,8 @@ exportGame :: proc(game: ^Game, filename: string) {
w: csv.Writer
csv.writer_init(&w, stream)
// We will store all rows as slices of strings. We will be allocating
// memory for the strings, so we need to free that memory too.
records: [dynamic][]string
defer {
for record in records {
@ -189,7 +195,27 @@ exportGame :: proc(game: ^Game, filename: string) {
}
// import an existing game from a csv file
importGame :: proc(filename: string) -> ^Game {
// TODO
return nil
importGame :: proc(game: ^Game, filename: string) {
r: csv.Reader
r.trim_leading_space = true
r.reuse_record = true
r.reuse_record_buffer = true
defer csv.reader_destroy(&r)
csv_data, success := os.read_entire_file(filename, context.allocator)
defer delete(csv_data)
if success == true {
csv.reader_init_with_string(&r, string(csv_data))
} else {
fmt.eprintfln("Unable to open file: %v", filename)
return
}
for r, i, err in csv.iterator_next(&r) {
if err != nil { /* Do something with error */ }
for f, j in r {
fmt.printfln("Record %v, field %v: %q", i, j, f)
}
}
}