planetis-m / naylib

Yet another raylib Nim wrapper
MIT License
227 stars 10 forks source link

Avoid copies #3

Closed planetis-m closed 2 years ago

planetis-m commented 2 years ago

Copies can be avoided by using our own container types. Example:

type
  WaveSamples* = object
    len: int
    data: ptr UncheckedArray[float32]

proc `=destroy`*(x: var WaveSamples) =
  if x.data != nil: memFree(x.data)
proc `=copy`*(dest: var WaveSamples; source: WaveSamples) =
  if dest.data != source.data:
    `=destroy`(dest)
    wasMoved(dest)
    dest.len = source.len
    if dest.len > 0:
      dest.data = cast[typeof(dest.data)](memAlloc(dest.len.int32))
      copyMem(dest.data, source.data, dest.len * sizeof(float32))

proc loadWaveSamples*(wave: Wave): WaveSamples =
  ## Load samples data from wave as a floats array
  let data = loadWaveSamples(wave)
  let len = int(wave.frameCount * wave.channels)
  result = WaveSamples(len: len, data: data)

proc `[]`*(x: WaveSamples, i: int): Transform =
  rangeCheck x.data != nil and i.uint < x.len.uint
  result = x.data[i]

proc `[]`*(x: var WaveSamples, i: int): var Transform =
  rangeCheck x.data != nil and i.uint < x.len.uint
  result = x.data[i]

proc `[]=`*(x: var WaveSamples, i: int, val: Transform) =
  rangeCheck x.data != nil and i.uint < x.len.uint
  x.data[i] = val

template toOpenArray*(x: WaveSamples, first, last: int): untyped =
  toOpenArray(x.data, first, last)
planetis-m commented 2 years ago

Better yet make it generic