compatibility shims for web

This commit is contained in:
Nick Fisher
2024-05-11 22:38:28 +08:00
parent ae70564bf3
commit 85f129d435
6 changed files with 753 additions and 785 deletions

View File

@@ -1,8 +1,84 @@
import 'dart:async';
import 'dart:ffi';
import 'package:ffi/ffi.dart';
export 'package:ffi/ffi.dart';
export 'dart_filament.g.dart';
final allocator = calloc;
Future<void> withVoidCallback(
Function(Pointer<NativeFunction<Void Function()>>) func) async {
final completer = Completer();
// ignore: prefer_function_declarations_over_variables
void Function() callback = () {
completer.complete();
};
final nativeCallable = NativeCallable<Void Function()>.listener(callback);
func.call(nativeCallable.nativeFunction);
await completer.future;
nativeCallable.close();
}
Future<Pointer<Void>> withVoidPointerCallback(
Function(Pointer<NativeFunction<Void Function(Pointer<Void>)>>)
func) async {
final completer = Completer<Pointer<Void>>();
// ignore: prefer_function_declarations_over_variables
void Function(Pointer<Void>) callback = (Pointer<Void> ptr) {
completer.complete(ptr);
};
final nativeCallable =
NativeCallable<Void Function(Pointer<Void>)>.listener(callback);
func.call(nativeCallable.nativeFunction);
await completer.future;
nativeCallable.close();
return completer.future;
}
Future<bool> withBoolCallback(
Function(Pointer<NativeFunction<Void Function(Bool)>>) func) async {
final completer = Completer<bool>();
// ignore: prefer_function_declarations_over_variables
void Function(bool) callback = (bool result) {
completer.complete(result);
};
final nativeCallable = NativeCallable<Void Function(Bool)>.listener(callback);
func.call(nativeCallable.nativeFunction);
await completer.future;
nativeCallable.close();
return completer.future;
}
Future<int> withIntCallback(
Function(Pointer<NativeFunction<Void Function(Int32)>>) func) async {
final completer = Completer<int>();
// ignore: prefer_function_declarations_over_variables
void Function(int) callback = (int result) {
completer.complete(result);
};
final nativeCallable =
NativeCallable<Void Function(Int32)>.listener(callback);
func.call(nativeCallable.nativeFunction);
await completer.future;
nativeCallable.close();
return completer.future;
}
Future<String> withCharPtrCallback(
Function(Pointer<NativeFunction<Void Function(Pointer<Char>)>>)
func) async {
final completer = Completer<String>();
// ignore: prefer_function_declarations_over_variables
void Function(Pointer<Char>) callback = (Pointer<Char> result) {
completer.complete(result.cast<Utf8>().toDartString());
};
final nativeCallable =
NativeCallable<Void Function(Pointer<Char>)>.listener(callback);
func.call(nativeCallable.nativeFunction);
await completer.future;
nativeCallable.close();
return completer.future;
}
class Compatibility {}

View File

@@ -0,0 +1,221 @@
import 'dart:ffi';
export "allocator.dart";
export "dart_filament.g.dart";
import 'dart:convert';
import 'dart:ffi' as ffi hide Uint8Pointer, FloatPointer;
import 'dart:typed_data';
import 'package:dart_filament/dart_filament/compatibility/web/dart_filament.g.dart';
import 'package:ffi/ffi.dart';
export 'package:ffi/ffi.dart' hide StringUtf8Pointer, Utf8Pointer;
export 'dart:ffi'
hide
Uint8Pointer,
FloatPointer,
DoublePointer,
Int32Pointer,
Int64Pointer,
PointerPointer, Allocator;
class Allocator implements ffi.Allocator {
const Allocator();
@override
ffi.Pointer<T> allocate<T extends ffi.NativeType>(int byteCount,
{int? alignment}) {
return flutter_filament_web_allocate(byteCount).cast<T>();
}
@override
void free(ffi.Pointer<ffi.NativeType> pointer) {
flutter_filament_web_free(pointer.cast<ffi.Void>());
}
}
extension CharPointer on ffi.Pointer<ffi.Char> {
int get value {
return flutter_filament_web_get(this, 0);
}
set value(int value) {
flutter_filament_web_set(this, 0, value);
}
void operator []=(int index, int value) {
this.elementAt(index).value = value;
}
ffi.Pointer<ffi.Char> elementAt(int index) =>
ffi.Pointer.fromAddress(address + ffi.sizeOf<ffi.Char>() * index);
}
extension IntPointer on ffi.Pointer<ffi.Int> {
int get value {
return flutter_filament_web_get_int32(this.cast<ffi.Int32>(), 0);
}
set value(int value) {
flutter_filament_web_set_int32(this.cast<ffi.Int32>(), 0, value);
}
void operator []=(int index, int value) {
this.elementAt(index).value = value;
}
int operator [](int index) {
return this.elementAt(index).value;
}
ffi.Pointer<ffi.Int> elementAt(int index) =>
ffi.Pointer.fromAddress(address + ffi.sizeOf<ffi.Int>() * index);
}
extension Int32Pointer on ffi.Pointer<ffi.Int32> {
int get value {
return flutter_filament_web_get_int32(this, 0);
}
set value(int value) {
flutter_filament_web_set_int32(this, 0, value);
}
void operator []=(int index, int value) {
this.elementAt(index).value = value;
}
int operator [](int index) {
return this.elementAt(index).value;
}
ffi.Pointer<ffi.Int32> elementAt(int index) =>
ffi.Pointer.fromAddress(address + ffi.sizeOf<ffi.Int32>() * index);
}
extension UInt8Pointer on ffi.Pointer<ffi.Uint8> {
int get value {
return flutter_filament_web_get(this.cast<ffi.Char>(), 0);
}
set value(int value) {
flutter_filament_web_set(this.cast<ffi.Char>(), 0, value);
}
void operator []=(int index, int value) {
this.elementAt(index).value = value;
}
int operator [](int index) {
return this.elementAt(index).value;
}
ffi.Pointer<ffi.Uint8> elementAt(int index) =>
ffi.Pointer.fromAddress(address + ffi.sizeOf<ffi.Uint8>() * index);
}
extension PointerPointer<T extends ffi.NativeType>
on ffi.Pointer<ffi.Pointer<T>> {
ffi.Pointer<T> get value {
return flutter_filament_web_get_pointer(cast<ffi.Pointer<ffi.Void>>(), 0)
.cast<T>();
}
set value(ffi.Pointer<T> value) {
flutter_filament_web_set_pointer(
cast<ffi.Pointer<ffi.Void>>(), 0, value.cast<ffi.Void>());
}
void operator []=(int index, ffi.Pointer<T> value) {
this.elementAt(index).value = value;
}
ffi.Pointer<ffi.Pointer<T>> elementAt(int index) =>
ffi.Pointer.fromAddress(address + ffi.sizeOf<ffi.Pointer>() * index);
}
extension FloatPointer on ffi.Pointer<ffi.Float> {
double get value {
return flutter_filament_web_get_float(this, 0);
}
set value(double value) {
flutter_filament_web_set_float(this, 0, value);
}
void operator []=(int index, double value) {
this.elementAt(index).value = value;
}
ffi.Pointer<ffi.Float> elementAt(int index) =>
ffi.Pointer.fromAddress(address + ffi.sizeOf<ffi.Float>() * index);
}
extension StringConversion on String {
ffi.Pointer<Utf8> toNativeUtf8({ffi.Allocator? allocator}) {
final units = utf8.encode(this);
final ffi.Pointer<ffi.Uint8> result =
allocator!<ffi.Uint8>(units.length + 1);
for (int i = 0; i < units.length; i++) {
result.elementAt(i).value = units[i];
}
result.elementAt(units.length).value = 0;
return result.cast();
}
}
extension StringUtf8Pointer on ffi.Pointer<Utf8> {
static int _length(ffi.Pointer<ffi.Uint8> codeUnits) {
var length = 0;
while (codeUnits[length] != 0) {
length++;
}
return length;
}
String toDartString({int? length}) {
final codeUnits = this.cast<ffi.Uint8>();
final list = <int>[];
if (length != null) {
RangeError.checkNotNegative(length, 'length');
} else {
length = _length(codeUnits);
}
for (int i = 0; i < length; i++) {
list.add(codeUnits.elementAt(i).value);
}
return utf8.decode(list);
}
}
extension DoublePointer on ffi.Pointer<ffi.Double> {
double get value {
return flutter_filament_web_get_double(this, 0);
}
set value(double value) {
return flutter_filament_web_set_double(this, 0, value);
}
Float64List asTypedList(int length) {
var list = Float64List(length);
for (int i = 0; i < length; i++) {
list[i] = elementAt(i).value;
}
return list;
}
double operator [](int index) {
return elementAt(index).value;
}
void operator []=(int index, double value) {
elementAt(index).value = value;
}
ffi.Pointer<ffi.Double> elementAt(int index) =>
ffi.Pointer.fromAddress(address + ffi.sizeOf<ffi.Double>() * index);
}

View File

@@ -1,14 +1,12 @@
import 'dart:ffi';
import 'dart:async';
import 'dart:js_interop';
import 'package:dart_filament/dart_filament/compatibility/web/interop.dart';
import "allocator.dart";
export "allocator.dart";
export "dart_filament.g.dart";
import 'dart:convert';
import 'dart:ffi' as ffi hide Uint8Pointer, FloatPointer;
import 'dart:typed_data';
import 'package:dart_filament/dart_filament/compatibility/web/dart_filament.g.dart';
import 'package:ffi/ffi.dart';
export 'package:ffi/ffi.dart' hide StringUtf8Pointer, Utf8Pointer;
export 'dart:ffi'
hide
@@ -16,210 +14,11 @@ export 'dart:ffi'
FloatPointer,
DoublePointer,
Int32Pointer,
Int64Pointer;
Int64Pointer,
PointerPointer,
Allocator;
class _Allocator implements ffi.Allocator {
const _Allocator();
@override
ffi.Pointer<T> allocate<T extends ffi.NativeType>(int byteCount,
{int? alignment}) {
return flutter_filament_web_allocate(byteCount).cast<T>();
}
@override
void free(ffi.Pointer<ffi.NativeType> pointer) {
flutter_filament_web_free(pointer.cast<ffi.Void>());
}
}
const allocator = _Allocator();
extension CharPointer on ffi.Pointer<ffi.Char> {
int get value {
return flutter_filament_web_get(this, 0);
}
set value(int value) {
flutter_filament_web_set(this, 0, value);
}
void operator []=(int index, int value) {
this.elementAt(index).value = value;
}
ffi.Pointer<ffi.Char> elementAt(int index) =>
ffi.Pointer.fromAddress(address + ffi.sizeOf<ffi.Char>() * index);
}
extension IntPointer on ffi.Pointer<ffi.Int> {
int get value {
return flutter_filament_web_get_int32(this.cast<ffi.Int32>(), 0);
}
set value(int value) {
flutter_filament_web_set_int32(this.cast<ffi.Int32>(), 0, value);
}
void operator []=(int index, int value) {
this.elementAt(index).value = value;
}
int operator [](int index) {
return this.elementAt(index).value;
}
ffi.Pointer<ffi.Int> elementAt(int index) =>
ffi.Pointer.fromAddress(address + ffi.sizeOf<ffi.Int>() * index);
}
extension Int32Pointer on ffi.Pointer<ffi.Int32> {
int get value {
return flutter_filament_web_get_int32(this, 0);
}
set value(int value) {
flutter_filament_web_set_int32(this, 0, value);
}
void operator []=(int index, int value) {
this.elementAt(index).value = value;
}
int operator [](int index) {
return this.elementAt(index).value;
}
ffi.Pointer<ffi.Int32> elementAt(int index) =>
ffi.Pointer.fromAddress(address + ffi.sizeOf<ffi.Int32>() * index);
}
extension UInt8Pointer on ffi.Pointer<ffi.Uint8> {
int get value {
return flutter_filament_web_get(this.cast<ffi.Char>(), 0);
}
set value(int value) {
flutter_filament_web_set(this.cast<ffi.Char>(), 0, value);
}
void operator []=(int index, int value) {
this.elementAt(index).value = value;
}
int operator [](int index) {
return this.elementAt(index).value;
}
ffi.Pointer<ffi.Uint8> elementAt(int index) =>
ffi.Pointer.fromAddress(address + ffi.sizeOf<ffi.Uint8>() * index);
}
extension PointerPointer<T extends ffi.NativeType>
on ffi.Pointer<ffi.Pointer<T>> {
ffi.Pointer<T> get value {
return flutter_filament_web_get_pointer(cast<ffi.Pointer<ffi.Void>>(), 0)
.cast<T>();
}
set value(ffi.Pointer<T> value) {
flutter_filament_web_set_pointer(
cast<ffi.Pointer<ffi.Void>>(), 0, value.cast<ffi.Void>());
}
void operator []=(int index, ffi.Pointer<T> value) {
this.elementAt(index).value = value;
}
ffi.Pointer<ffi.Pointer<T>> elementAt(int index) =>
ffi.Pointer.fromAddress(address + ffi.sizeOf<ffi.Pointer>() * index);
}
extension FloatPointer on ffi.Pointer<ffi.Float> {
double get value {
return flutter_filament_web_get_float(this, 0);
}
set value(double value) {
flutter_filament_web_set_float(this, 0, value);
}
void operator []=(int index, double value) {
this.elementAt(index).value = value;
}
ffi.Pointer<ffi.Float> elementAt(int index) =>
ffi.Pointer.fromAddress(address + ffi.sizeOf<ffi.Float>() * index);
}
extension StringConversion on String {
ffi.Pointer<Utf8> toNativeUtf8({ffi.Allocator? allocator}) {
final units = utf8.encode(this);
final ffi.Pointer<ffi.Uint8> result =
allocator!<ffi.Uint8>(units.length + 1);
for (int i = 0; i < units.length; i++) {
result.elementAt(i).value = units[i];
}
result.elementAt(units.length).value = 0;
return result.cast();
}
}
extension StringUtf8Pointer on ffi.Pointer<Utf8> {
static int _length(ffi.Pointer<ffi.Uint8> codeUnits) {
var length = 0;
while (codeUnits[length] != 0) {
length++;
}
return length;
}
String toDartString({int? length}) {
final codeUnits = this.cast<ffi.Uint8>();
final list = <int>[];
if (length != null) {
RangeError.checkNotNegative(length, 'length');
} else {
length = _length(codeUnits);
}
for (int i = 0; i < length; i++) {
list.add(codeUnits.elementAt(i).value);
}
return utf8.decode(list);
}
}
extension DoublePointer on ffi.Pointer<ffi.Double> {
double get value {
return flutter_filament_web_get_double(this, 0);
}
set value(double value) {
return flutter_filament_web_set_double(this, 0, value);
}
Float64List asTypedList(int length) {
var list = Float64List(length);
for (int i = 0; i < length; i++) {
list[i] = elementAt(i).value;
}
return list;
}
double operator [](int index) {
return elementAt(index).value;
}
void operator []=(int index, double value) {
elementAt(index).value = value;
}
ffi.Pointer<ffi.Double> elementAt(int index) =>
ffi.Pointer.fromAddress(address + ffi.sizeOf<ffi.Double>() * index);
}
const allocator = Allocator();
@AbiSpecificIntegerMapping({
Abi.androidArm: Uint8(),
@@ -252,3 +51,68 @@ final class FooChar extends AbiSpecificInteger {
class Compatibility {
final _foo = FooChar();
}
Future<void> withVoidCallback(
Function(Pointer<NativeFunction<Void Function()>>) func) async {
JSArray retVal = createVoidCallback();
var promise = retVal.toDart[0] as JSPromise<JSNumber>;
var fnPtrAddress = retVal.toDart[1] as JSNumber;
var fnPtr = Pointer<NativeFunction<Void Function()>>.fromAddress(
fnPtrAddress.toDartInt);
func(fnPtr);
await promise.toDart;
}
Future<int> withVoidPointerCallback(
void Function(Pointer<NativeFunction<Void Function(Pointer<Void>)>>)
func) async {
JSArray retVal = createVoidPointerCallback();
var promise = retVal.toDart[0] as JSPromise<JSNumber>;
var fnPtrAddress = retVal.toDart[1] as JSNumber;
var fnPtr = Pointer<NativeFunction<Void Function(Pointer<Void>)>>.fromAddress(
fnPtrAddress.toDartInt);
func(fnPtr);
final addr = await promise.toDart;
return addr.toDartInt;
}
Future<bool> withBoolCallback(
Function(Pointer<NativeFunction<Void Function(Bool)>>) func) async {
JSArray retVal = createBoolCallback();
var promise = retVal.toDart[0] as JSPromise<JSBoolean>;
var fnPtrAddress = retVal.toDart[1] as JSNumber;
var fnPtr = Pointer<NativeFunction<Void Function(Bool)>>.fromAddress(
fnPtrAddress.toDartInt);
func(fnPtr);
final addr = await promise.toDart;
return addr.toDart;
}
Future<int> withIntCallback(
Function(Pointer<NativeFunction<Void Function(Int32)>>) func) async {
JSArray retVal = createBoolCallback();
var promise = retVal.toDart[0] as JSPromise<JSNumber>;
var fnPtrAddress = retVal.toDart[1] as JSNumber;
var fnPtr = Pointer<NativeFunction<Void Function(Int32)>>.fromAddress(
fnPtrAddress.toDartInt);
func(fnPtr);
final addr = await promise.toDart;
return addr.toDartInt;
}
Future<String> withCharPtrCallback(
Function(Pointer<NativeFunction<Void Function(Pointer<Char>)>>)
func) async {
JSArray retVal = createVoidPointerCallback();
var promise = retVal.toDart[0] as JSPromise<JSNumber>;
var fnPtrAddress = retVal.toDart[1] as JSNumber;
var fnPtr = Pointer<NativeFunction<Void Function(Pointer<Char>)>>.fromAddress(
fnPtrAddress.toDartInt);
func(fnPtr);
final addr = await promise.toDart;
return Pointer<Utf8>.fromAddress(addr.toDartInt).toDartString();
}

View File

@@ -0,0 +1,16 @@
import 'dart:js_interop';
@JS()
external JSArray createIntCallback();
@JS()
external JSArray createBoolCallback();
@JS()
external JSArray createVoidPointerCallback();
@JS()
external JSArray createVoidCallback();

View File

@@ -9,7 +9,6 @@ import 'abstract_filament_viewer.dart';
import 'scene.dart';
import 'compatibility/compatibility.dart';
// ignore: constant_identifier_names
const FilamentEntity _FILAMENT_ASSET_ERROR = 0;
@@ -37,7 +36,7 @@ class FilamentViewer extends AbstractFilamentViewer {
final _pickResultController =
StreamController<FilamentPickResult>.broadcast();
final Pointer<ResourceLoaderWrapper> resourceLoader;
final Pointer<Void> resourceLoader;
var _driver = nullptr.cast<Void>();
@@ -62,20 +61,20 @@ class FilamentViewer extends AbstractFilamentViewer {
this._driver = driver ?? nullptr;
this._sharedContext = sharedContext ?? nullptr;
_onPickResultCallable =
NativeCallable<Void Function(Int32 entityId, Int x, Int y)>.listener(
_onPickResult);
// _onPickResultCallable =
// NativeCallable<Void Function(Int32 entityId, Int x, Int y)>.listener(
// _onPickResult);
_initialize();
}
Future createRenderTarget(
double width, double height, int textureHandle) async {
await _withVoidCallback((callback) => create_render_target_ffi(
await withVoidCallback((callback) => create_render_target_ffi(
_viewer!, textureHandle, width.toInt(), height.toInt(), callback));
}
Future updateViewportAndCameraProjection(double width, double height) async {
await _withVoidCallback((callback) {
await withVoidCallback((callback) {
update_viewport_and_camera_projection_ffi(
_viewer!, width.toInt(), height.toInt(), 1.0, callback);
});
@@ -83,27 +82,36 @@ class FilamentViewer extends AbstractFilamentViewer {
Future createSwapChain(double width, double height,
{Pointer<Void>? surface}) async {
await _withVoidCallback((callback) {
await withVoidCallback((callback) {
create_swap_chain_ffi(_viewer!, surface ?? nullptr, width.toInt(),
height.toInt(), callback);
});
}
Future destroySwapChain() async {
await _withVoidCallback((callback) {
await withVoidCallback((callback) {
destroy_swap_chain_ffi(_viewer!, callback);
});
}
Future _initialize() async {
final uberarchivePtr =
uberArchivePath?.toNativeUtf8().cast<Char>() ?? nullptr;
uberArchivePath?.toNativeUtf8(allocator:allocator).cast<Char>() ?? nullptr;
var viewer = await withVoidPointerCallback(
(Pointer<NativeFunction<Void Function(Pointer<Void>)>> callback) {
create_filament_viewer_ffi(_sharedContext, _driver, uberarchivePtr,
resourceLoader, _renderCallback, _renderCallbackOwner, callback);
});
print(viewer);
if (viewer is int) {
_viewer = Pointer.fromAddress(viewer);
} else {
_viewer = (viewer as Pointer<Void>);
}
_viewer = await _withVoidPointerCallback((callback) =>
create_filament_viewer_ffi(_sharedContext, _driver, uberarchivePtr,
resourceLoader, _renderCallback, _renderCallbackOwner, callback));
print("Set viewer to $_viewer");
allocator.free(uberarchivePtr);
print("Set viewer to $_viewer");
print("Created viewer ${_viewer!.address}");
if (_viewer!.address == 0) {
@@ -146,81 +154,6 @@ class FilamentViewer extends AbstractFilamentViewer {
_viewer = null;
}
Future<void> _withVoidCallback(
Function(Pointer<NativeFunction<Void Function()>>) func) async {
final completer = Completer();
// ignore: prefer_function_declarations_over_variables
void Function() callback = () {
completer.complete();
};
final nativeCallable = NativeCallable<Void Function()>.listener(callback);
func.call(nativeCallable.nativeFunction);
await completer.future;
nativeCallable.close();
}
Future<Pointer<Void>> _withVoidPointerCallback(
Function(Pointer<NativeFunction<Void Function(Pointer<Void>)>>)
func) async {
final completer = Completer<Pointer<Void>>();
// ignore: prefer_function_declarations_over_variables
void Function(Pointer<Void>) callback = (Pointer<Void> ptr) {
completer.complete(ptr);
};
final nativeCallable =
NativeCallable<Void Function(Pointer<Void>)>.listener(callback);
func.call(nativeCallable.nativeFunction);
await completer.future;
nativeCallable.close();
return completer.future;
}
Future<bool> _withBoolCallback(
Function(Pointer<NativeFunction<Void Function(Bool)>>) func) async {
final completer = Completer<bool>();
// ignore: prefer_function_declarations_over_variables
void Function(bool) callback = (bool result) {
completer.complete(result);
};
final nativeCallable =
NativeCallable<Void Function(Bool)>.listener(callback);
func.call(nativeCallable.nativeFunction);
await completer.future;
nativeCallable.close();
return completer.future;
}
Future<int> _withIntCallback(
Function(Pointer<NativeFunction<Void Function(Int32)>>) func) async {
final completer = Completer<int>();
// ignore: prefer_function_declarations_over_variables
void Function(int) callback = (int result) {
completer.complete(result);
};
final nativeCallable =
NativeCallable<Void Function(Int32)>.listener(callback);
func.call(nativeCallable.nativeFunction);
await completer.future;
nativeCallable.close();
return completer.future;
}
Future<String> _withCharPtrCallback(
Function(Pointer<NativeFunction<Void Function(Pointer<Char>)>>)
func) async {
final completer = Completer<String>();
// ignore: prefer_function_declarations_over_variables
void Function(Pointer<Char>) callback = (Pointer<Char> result) {
completer.complete(result.cast<Utf8>().toDartString());
};
final nativeCallable =
NativeCallable<Void Function(Pointer<Char>)>.listener(callback);
func.call(nativeCallable.nativeFunction);
await completer.future;
nativeCallable.close();
return completer.future;
}
@override
Future clearBackgroundImage() async {
clear_background_image_ffi(_viewer!);
@@ -228,8 +161,8 @@ class FilamentViewer extends AbstractFilamentViewer {
@override
Future setBackgroundImage(String path, {bool fillHeight = false}) async {
final pathPtr = path.toNativeUtf8().cast<Char>();
await _withVoidCallback((cb) {
final pathPtr = path.toNativeUtf8(allocator:allocator).cast<Char>();
await withVoidCallback((cb) {
set_background_image_ffi(_viewer!, pathPtr, fillHeight, cb);
});
@@ -249,8 +182,10 @@ class FilamentViewer extends AbstractFilamentViewer {
@override
Future loadSkybox(String skyboxPath) async {
final pathPtr = skyboxPath.toNativeUtf8().cast<Char>();
await _withVoidCallback((cb) {
final pathPtr = skyboxPath.toNativeUtf8(allocator: allocator).cast<Char>();
await withVoidCallback((cb) {
load_skybox_ffi(_viewer!, pathPtr, cb);
});
@@ -259,7 +194,7 @@ class FilamentViewer extends AbstractFilamentViewer {
@override
Future loadIbl(String lightingPath, {double intensity = 30000}) async {
final pathPtr = lightingPath.toNativeUtf8().cast<Char>();
final pathPtr = lightingPath.toNativeUtf8(allocator:allocator).cast<Char>();
load_ibl_ffi(_viewer!, pathPtr, intensity);
}
@@ -295,7 +230,7 @@ class FilamentViewer extends AbstractFilamentViewer {
double dirY,
double dirZ,
bool castShadows) async {
var entity = await _withIntCallback((callback) => add_light_ffi(
var entity = await withIntCallback((callback) => add_light_ffi(
_viewer!,
type,
colour,
@@ -328,7 +263,7 @@ class FilamentViewer extends AbstractFilamentViewer {
@override
Future<FilamentEntity> createInstance(FilamentEntity entity) async {
var created = await _withIntCallback(
var created = await withIntCallback(
(callback) => create_instance(_sceneManager!, entity));
if (created == _FILAMENT_ASSET_ERROR) {
throw Exception("Failed to create instance");
@@ -360,8 +295,8 @@ class FilamentViewer extends AbstractFilamentViewer {
if (unlit) {
throw Exception("Not yet implemented");
}
final pathPtr = path.toNativeUtf8().cast<Char>();
var entity = await _withIntCallback((callback) =>
final pathPtr = path.toNativeUtf8(allocator:allocator).cast<Char>();
var entity = await withIntCallback((callback) =>
load_glb_ffi(_sceneManager!, pathPtr, numInstances, callback));
allocator.free(pathPtr);
if (entity == _FILAMENT_ASSET_ERROR) {
@@ -375,15 +310,15 @@ class FilamentViewer extends AbstractFilamentViewer {
@override
Future<FilamentEntity> loadGltf(String path, String relativeResourcePath,
{bool force = false}) async {
if (Platform.isWindows && !force) {
throw Exception(
"loadGltf has a race condition on Windows which is likely to crash your program. If you really want to try, pass force=true to loadGltf");
}
// if (Platform.isWindows && !force) {
// throw Exception(
// "loadGltf has a race condition on Windows which is likely to crash your program. If you really want to try, pass force=true to loadGltf");
// }
final pathPtr = path.toNativeUtf8().cast<Char>();
final pathPtr = path.toNativeUtf8(allocator:allocator).cast<Char>();
final relativeResourcePathPtr =
relativeResourcePath.toNativeUtf8().cast<Char>();
var entity = await _withIntCallback((callback) => load_gltf_ffi(
relativeResourcePath.toNativeUtf8(allocator:allocator).cast<Char>();
var entity = await withIntCallback((callback) => load_gltf_ffi(
_sceneManager!, pathPtr, relativeResourcePathPtr, callback));
allocator.free(pathPtr);
allocator.free(relativeResourcePathPtr);
@@ -437,7 +372,7 @@ class FilamentViewer extends AbstractFilamentViewer {
weightsPtr[i] = weights[i];
}
var success = await _withBoolCallback((cb) {
var success = await withBoolCallback((cb) {
set_morph_target_weights_ffi(
_sceneManager!, entity, weightsPtr, weights.length, cb);
});
@@ -454,9 +389,9 @@ class FilamentViewer extends AbstractFilamentViewer {
Future<List<String>> getMorphTargetNames(
FilamentEntity entity, String meshName) async {
var names = <String>[];
var meshNamePtr = meshName.toNativeUtf8().cast<Char>();
var meshNamePtr = meshName.toNativeUtf8(allocator:allocator).cast<Char>();
var count = await _withIntCallback((callback) =>
var count = await withIntCallback((callback) =>
get_morph_target_name_count_ffi(
_sceneManager!, entity, meshNamePtr, callback));
var outPtr = allocator<Char>(255);
@@ -632,13 +567,13 @@ class FilamentViewer extends AbstractFilamentViewer {
Future removeEntity(FilamentEntity entity) async {
_scene.unregisterEntity(entity);
await _withVoidCallback(
await withVoidCallback(
(callback) => remove_entity_ffi(_viewer!, entity, callback));
}
@override
Future clearEntities() async {
await _withVoidCallback(
await withVoidCallback(
(callback) => clear_entities_ffi(_viewer!, callback));
_scene.clearEntities();
}
@@ -717,7 +652,7 @@ class FilamentViewer extends AbstractFilamentViewer {
@override
Future setCamera(FilamentEntity entity, String? name) async {
var cameraNamePtr = name?.toNativeUtf8().cast<Char>() ?? nullptr;
var cameraNamePtr = name?.toNativeUtf8(allocator:allocator).cast<Char>() ?? nullptr;
var result = set_camera(_viewer!, entity, cameraNamePtr);
allocator.free(cameraNamePtr);
if (!result) {
@@ -816,7 +751,7 @@ class FilamentViewer extends AbstractFilamentViewer {
@override
Future setMaterialColor(FilamentEntity entity, String meshName,
int materialIndex, double r, double g, double b, double a) async {
var meshNamePtr = meshName.toNativeUtf8().cast<Char>();
var meshNamePtr = meshName.toNativeUtf8(allocator:allocator).cast<Char>();
var result = set_material_color(
_sceneManager!, entity, meshNamePtr, materialIndex, r, g, b, a);
allocator.free(meshNamePtr);
@@ -878,14 +813,14 @@ class FilamentViewer extends AbstractFilamentViewer {
@override
Future hide(FilamentEntity entity, String? meshName) async {
final meshNamePtr = meshName?.toNativeUtf8().cast<Char>() ?? nullptr;
final meshNamePtr = meshName?.toNativeUtf8(allocator:allocator).cast<Char>() ?? nullptr;
if (hide_mesh(_sceneManager!, entity, meshNamePtr) != 1) {}
allocator.free(meshNamePtr);
}
@override
Future reveal(FilamentEntity entity, String? meshName) async {
final meshNamePtr = meshName?.toNativeUtf8().cast<Char>() ?? nullptr;
final meshNamePtr = meshName?.toNativeUtf8(allocator:allocator).cast<Char>() ?? nullptr;
final result = reveal_mesh(_sceneManager!, entity, meshNamePtr) == 1;
allocator.free(meshNamePtr);
if (!result) {
@@ -1165,7 +1100,7 @@ class FilamentViewer extends AbstractFilamentViewer {
indicesPtr.elementAt(i).value = indices[i];
}
var entity = await _withIntCallback((callback) => create_geometry_ffi(
var entity = await withIntCallback((callback) => create_geometry_ffi(
_viewer!,
vertexPtr,
vertices.length,