mgpuReadAsyncInt64 function

Future<void> mgpuReadAsyncInt64(
  1. MGPUBuffer buffer,
  2. TypedData outputData, {
  3. int readElements = 0,
  4. int elementOffset = 0,
})

Implementation

Future<void> mgpuReadAsyncInt64(
  MGPUBuffer buffer,
  // Note: Dart web doesn't have Int64List directly, use ByteData or handle BigInt conversion
  // Assuming caller provides appropriate ByteData or handles conversion from Uint8List view
  TypedData outputData, {
  int readElements = 0,
  int elementOffset = 0,
}) async {
  final int bytesPerElem = 8; // Int64
  final int elementsToRead = (readElements > 0)
      ? readElements
      : ((outputData.lengthInBytes ~/ bytesPerElem) - elementOffset);
  final int sizeToAllocate = elementsToRead * bytesPerElem;

  if (elementsToRead <= 0 ||
      elementOffset < 0 ||
      (elementOffset * bytesPerElem) >= outputData.lengthInBytes)
    return;

  final JSNumber ptr = _malloc(sizeToAllocate.toJS);
  // Byte index for heap copy
  final int startByteIndex = ptr.toDartInt;

  try {
    await ccall(
      "mgpuReadSyncInt64".toJS, // Use sync C++ function
      "void".toJS,
      ["number", "number", "number", "number"].toJSDeep,
      [buffer, ptr, elementsToRead.toJS, elementOffset.toJS].toJSDeep,
      {"async": true}.toJSDeep,
    ).toDart;

    final heapBytes = _heapU8.sublist(
      startByteIndex,
      startByteIndex + sizeToAllocate,
    );

    if (outputData is ByteData) {
      // Ensure we don't write past the end of the ByteData buffer
      final int bytesAvailableInOut =
          outputData.lengthInBytes - (elementOffset * bytesPerElem);
      final int bytesToCopy = sizeToAllocate <= bytesAvailableInOut
          ? sizeToAllocate
          : bytesAvailableInOut;
      if (bytesToCopy > 0) {
        final outputBytes = Uint8List.view(
          outputData.buffer,
          outputData.offsetInBytes + (elementOffset * bytesPerElem),
          bytesToCopy,
        );
        outputBytes.setRange(0, bytesToCopy, heapBytes.sublist(0, bytesToCopy));
      }
    } else if (outputData is Uint8List) {
      // Allow direct copy if caller uses Uint8List
      final int bytesAvailableInOut =
          outputData.lengthInBytes - (elementOffset * bytesPerElem);
      final int bytesToCopy = sizeToAllocate <= bytesAvailableInOut
          ? sizeToAllocate
          : bytesAvailableInOut;
      if (bytesToCopy > 0) {
        outputData.setRange(
          elementOffset * bytesPerElem,
          (elementOffset * bytesPerElem) + bytesToCopy,
          heapBytes.sublist(0, bytesToCopy),
        );
      }
    } else {
      // Consider throwing an error for unsupported outputData types for Int64
      print(
        "Warning: mgpuReadAsyncInt64 expects outputData to be ByteData or Uint8List",
      );
    }
  } finally {
    _free(ptr);
  }
}