Skip to content

Commit

Permalink
feat: support double types in collections (#262)
Browse files Browse the repository at this point in the history
  • Loading branch information
halildurmus committed Jun 22, 2023
1 parent f52771b commit 78dd288
Show file tree
Hide file tree
Showing 13 changed files with 843 additions and 15 deletions.
20 changes: 18 additions & 2 deletions packages/windows_foundation/lib/src/collections/iiterable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,20 @@ interface class IIterable<T> extends IInspectable {
// vtable begins at 6, is 1 entries long.
final T Function(Pointer<COMObject>)? _creator;
final T Function(int)? _enumCreator;
final DoubleType? _doubleType;
final IntType? _intType;

/// Creates an instance of [IIterable] from the given [ptr].
///
/// [T] must be of type `bool`, `Guid`, `int`, `String`, `Uri`,
/// [T] must be of type `bool`, `double`, `Guid`, `int`, `String`, `Uri`,
/// `IInspectable` (e.g.`StorageFile`) or `WinRTEnum` (e.g. `DeviceClass`).
///
/// [doubleType] must be specified if [T] is `double`.
/// ```dart
/// final iterable =
/// IIterable<double>.fromPtr(ptr, doubleType: DoubleType.float);
/// ```
///
/// [intType] must be specified if [T] is `int`.
/// ```dart
/// final iterable = IIterable<int>.fromPtr(ptr, intType: IntType.uint64);
Expand All @@ -44,10 +51,16 @@ interface class IIterable<T> extends IInspectable {
super.ptr, {
T Function(Pointer<COMObject>)? creator,
T Function(int)? enumCreator,
DoubleType? doubleType,
IntType? intType,
}) : _creator = creator,
_enumCreator = enumCreator,
_doubleType = doubleType,
_intType = intType {
if (doubleType == null && this is IIterable<double>) {
throw ArgumentError.notNull('doubleType');
}

if (intType == null && this is IIterable<int>) {
throw ArgumentError.notNull('intType');
}
Expand Down Expand Up @@ -83,6 +96,9 @@ interface class IIterable<T> extends IInspectable {
}

return IIterator.fromPtr(retValuePtr,
creator: _creator, enumCreator: _enumCreator, intType: _intType);
creator: _creator,
enumCreator: _enumCreator,
doubleType: _doubleType,
intType: _intType);
}
}
18 changes: 17 additions & 1 deletion packages/windows_foundation/lib/src/collections/iiterator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,15 @@ abstract interface class IIterator<T> extends IInspectable {

/// Creates an instance of [IIterator] from the given [ptr].
///
/// [T] must be of type `bool`, `Guid`, `int`, `String`, `Uri`,
/// [T] must be of type `bool`, `double` `Guid`, `int`, `String`, `Uri`,
/// `IInspectable` (e.g.`StorageFile`) or `WinRTEnum` (e.g. `DeviceClass`).
///
/// [doubleType] must be specified if [T] is `double`.
/// ```dart
/// final iterator =
/// IIterator<double>.fromPtr(ptr, doubleType: DoubleType.float);
/// ```
///
/// [intType] must be specified if [T] is `int`.
/// ```dart
/// final iterator = IIterator<int>.fromPtr(ptr, intType: IntType.uint64);
Expand All @@ -42,11 +48,21 @@ abstract interface class IIterator<T> extends IInspectable {
Pointer<COMObject> ptr, {
T Function(Pointer<COMObject>)? creator,
T Function(int)? enumCreator,
DoubleType? doubleType,
IntType? intType,
}) {
if (T == bool) return _IIteratorBool.fromPtr(ptr) as IIterator<T>;
if (T == Guid) return _IIteratorGuid.fromPtr(ptr) as IIterator<T>;

if (T == double) {
if (doubleType == null) throw ArgumentError.notNull('doubleType');
final iterator = switch (doubleType) {
DoubleType.double => _IIteratorDouble.fromPtr(ptr),
DoubleType.float => _IIteratorFloat.fromPtr(ptr),
};
return iterator as IIterator<T>;
}

if (T == int) {
if (intType == null) throw ArgumentError.notNull('intType');
final iterator = switch (intType) {
Expand Down
130 changes: 130 additions & 0 deletions packages/windows_foundation/lib/src/collections/iiterator_part.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,136 @@ final class _IIteratorBool extends IIterator<bool> {
}
}

final class _IIteratorDouble extends IIterator<double> {
_IIteratorDouble.fromPtr(super.ptr);

@override
double get current {
final retValuePtr = calloc<Double>();

try {
final hr = ptr.ref.vtable
.elementAt(6)
.cast<
Pointer<
NativeFunction<
HRESULT Function(VTablePointer lpVtbl,
Pointer<Double> retValuePtr)>>>()
.value
.asFunction<
int Function(VTablePointer lpVtbl,
Pointer<Double> retValuePtr)>()(ptr.ref.lpVtbl, retValuePtr);

if (FAILED(hr)) throw WindowsException(hr);

return retValuePtr.value;
} finally {
free(retValuePtr);
}
}

@override
int getMany(int itemsSize, List<double> items) {
final retValuePtr = calloc<Uint32>();

try {
final pItemsArray = calloc<Double>(itemsSize);

final hr = ptr.ref.vtable
.elementAt(9)
.cast<
Pointer<
NativeFunction<
HRESULT Function(
VTablePointer lpVtbl,
Uint32 itemsSize,
Pointer<Double> items,
Pointer<Uint32> retValuePtr)>>>()
.value
.asFunction<
int Function(VTablePointer lpVtbl, int itemsSize,
Pointer<Double> items, Pointer<Uint32> retValuePtr)>()(
ptr.ref.lpVtbl, itemsSize, pItemsArray, retValuePtr);

if (retValuePtr.value > 0) {
items.addAll(pItemsArray.toList(length: retValuePtr.value));
}
free(pItemsArray);

if (FAILED(hr)) throw WindowsException(hr);

return retValuePtr.value;
} finally {
free(retValuePtr);
}
}
}

final class _IIteratorFloat extends IIterator<double> {
_IIteratorFloat.fromPtr(super.ptr);

@override
double get current {
final retValuePtr = calloc<Float>();

try {
final hr = ptr.ref.vtable
.elementAt(6)
.cast<
Pointer<
NativeFunction<
HRESULT Function(
VTablePointer lpVtbl, Pointer<Float> retValuePtr)>>>()
.value
.asFunction<
int Function(VTablePointer lpVtbl,
Pointer<Float> retValuePtr)>()(ptr.ref.lpVtbl, retValuePtr);

if (FAILED(hr)) throw WindowsException(hr);

return retValuePtr.value;
} finally {
free(retValuePtr);
}
}

@override
int getMany(int itemsSize, List<double> items) {
final retValuePtr = calloc<Uint32>();

try {
final pItemsArray = calloc<Float>(itemsSize);

final hr = ptr.ref.vtable
.elementAt(9)
.cast<
Pointer<
NativeFunction<
HRESULT Function(
VTablePointer lpVtbl,
Uint32 itemsSize,
Pointer<Float> items,
Pointer<Uint32> retValuePtr)>>>()
.value
.asFunction<
int Function(VTablePointer lpVtbl, int itemsSize,
Pointer<Float> items, Pointer<Uint32> retValuePtr)>()(
ptr.ref.lpVtbl, itemsSize, pItemsArray, retValuePtr);

if (retValuePtr.value > 0) {
items.addAll(pItemsArray.toList(length: retValuePtr.value));
}
free(pItemsArray);

if (FAILED(hr)) throw WindowsException(hr);

return retValuePtr.value;
} finally {
free(retValuePtr);
}
}
}

final class _IIteratorGuid extends IIterator<Guid> {
_IIteratorGuid.fromPtr(super.ptr);

Expand Down
34 changes: 31 additions & 3 deletions packages/windows_foundation/lib/src/collections/ivector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@ abstract interface class IVector<T> extends IInspectable
required String iterableIid,
T Function(Pointer<COMObject>)? creator,
T Function(int)? enumCreator,
DoubleType? doubleType,
IntType? intType,
}) : _creator = creator,
_enumCreator = enumCreator,
_doubleType = doubleType,
_intType = intType,
_iterableIid = iterableIid;

final T Function(Pointer<COMObject>)? _creator;
final T Function(int)? _enumCreator;
final DoubleType? _doubleType;
final IntType? _intType;
final String _iterableIid;

Expand All @@ -41,12 +44,21 @@ abstract interface class IVector<T> extends IInspectable
/// [iterableIid] must be the IID of the `IIterable<T>` interface (e.g.
/// `'{9ac00304-83ea-5688-87b6-ae38aab65d0b}'`).
///
/// [T] must be of type `bool`, `Guid`, `int`, `String`, `Uri`,
/// [T] must be of type `bool`, `double`, `Guid`, `int`, `String`, `Uri`,
/// `IInspectable` (e.g.`StorageFile`) or `WinRTEnum` (e.g. `DeviceClass`).
///
/// [doubleType] must be specified if [T] is `double`.
/// ```dart
/// final vector = IVector<double>.fromPtr(ptr,
/// doubleType: DoubleType.float,
/// iterableIid: '{b01bee51-063a-5fda-bd72-d76637bb8cb8}');
/// ```
///
/// [intType] must be specified if [T] is `int`.
/// ```dart
/// final vector = IVector<int>.fromPtr(ptr, intType: IntType.uint64);
/// final vector = IVector<int>.fromPtr(ptr,
/// intType: IntType.uint64,
/// iterableIid: '{4b3a3229-7995-5f3c-b248-6c1f7e664f01}');
/// ```
///
/// [creator] must be specified if [T] is `IInspectable`.
Expand All @@ -67,6 +79,7 @@ abstract interface class IVector<T> extends IInspectable
required String iterableIid,
T Function(Pointer<COMObject>)? creator,
T Function(int)? enumCreator,
DoubleType? doubleType,
IntType? intType,
}) {
if (T == bool) {
Expand All @@ -83,6 +96,17 @@ abstract interface class IVector<T> extends IInspectable
creator: creator, iterableIid: iterableIid);
}

if (T == double) {
if (doubleType == null) throw ArgumentError.notNull('doubleType');
final vector = switch (doubleType) {
DoubleType.double => _IVectorDouble.fromPtr(ptr,
doubleType: doubleType, iterableIid: iterableIid),
DoubleType.float => _IVectorFloat.fromPtr(ptr,
doubleType: doubleType, iterableIid: iterableIid),
};
return vector as IVector<T>;
}

if (T == int) {
if (intType == null) throw ArgumentError.notNull('intType');
final vector = switch (intType) {
Expand Down Expand Up @@ -180,6 +204,7 @@ abstract interface class IVector<T> extends IInspectable
final vectorView = IVectorView<T>.fromPtr(retValuePtr,
creator: _creator,
enumCreator: _enumCreator,
doubleType: _doubleType,
intType: _intType,
iterableIid: _iterableIid);
return vectorView.toList();
Expand Down Expand Up @@ -243,7 +268,10 @@ abstract interface class IVector<T> extends IInspectable
void replaceAll(List<T> value);

late final _iIterable = IIterable<T>.fromPtr(toInterface(_iterableIid),
creator: _creator, enumCreator: _enumCreator, intType: _intType);
creator: _creator,
enumCreator: _enumCreator,
doubleType: _doubleType,
intType: _intType);

@override
IIterator<T> first() => _iIterable.first();
Expand Down

0 comments on commit 78dd288

Please sign in to comment.