gutter_runner/game/assets/parsers.odin

80 lines
1.5 KiB
Odin

package assets
import "core:bytes"
import "core:encoding/csv"
import "core:io"
import "core:log"
import "core:strconv"
Curve_Parse_Error :: enum {
Ok,
TooManyColumns,
ExpectedNumber,
}
parse_curve_2d :: proc(
data: []byte,
allocator := context.allocator,
) -> (
curve: Loaded_Curve_2D,
error: Curve_Parse_Error,
) {
bytes_reader: bytes.Reader
bytes.reader_init(&bytes_reader, data)
bytes_stream := bytes.reader_to_stream(&bytes_reader)
csv_reader: csv.Reader
csv.reader_init(&csv_reader, bytes_stream, context.temp_allocator)
defer csv.reader_destroy(&csv_reader)
tmp_result := make([dynamic][2]f32, context.temp_allocator)
skipped_header := false
for {
row, err := csv.read(&csv_reader, context.temp_allocator)
if err != nil {
if err != io.Error.EOF {
log.warnf("Failed to read curve %v", err)
}
break
}
if len(row) != 2 {
log.warnf("Curve expected 2 columns, got %v", len(row))
error = .TooManyColumns
break
}
ok: bool
key: f64
val: f64
key, ok = strconv.parse_f64(row[0])
if !ok {
if skipped_header {
log.warnf("Curve expected numbers, got %s", row[0])
error = .ExpectedNumber
break
}
skipped_header = true
continue
}
val, ok = strconv.parse_f64(row[1])
if !ok {
if skipped_header {
log.warnf("Curve expected numbers, got %s", row[1])
error = .ExpectedNumber
break
}
skipped_header = true
continue
}
append(&tmp_result, [2]f32{f32(key), f32(val)})
}
curve.points = make([][2]f32, len(tmp_result), allocator)
copy(curve.points, tmp_result[:])
return
}