gutter_runner/game/assets/parsers.odin

133 lines
2.6 KiB
Odin

package assets
import "core:bytes"
import "core:encoding/csv"
import "core:io"
import "core:log"
import "core:strconv"
CSV_Parse_Error :: enum {
Ok,
TooManyColumns,
ExpectedNumber,
}
parse_csv_1d :: proc(
data: []byte,
allocator := context.allocator,
) -> (
values: []f32,
error: CSV_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]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) != 1 {
log.warnf("expected 1 columns, got %v", len(row))
error = .TooManyColumns
break
}
val, ok := strconv.parse_f64(row[0])
if !ok {
if skipped_header {
log.warnf("Expected numbers, got %s", row[1])
error = .ExpectedNumber
break
}
skipped_header = true
continue
}
append(&tmp_result, f32(val))
}
values = make([]f32, len(tmp_result), allocator)
copy(values, tmp_result[:])
return
}
parse_csv_2d :: proc(
data: []byte,
allocator := context.allocator,
) -> (
curve: Loaded_Curve_2D,
error: CSV_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
}