Skip to content

Commit

Permalink
feat: support WinRTStruct type arguments in IAsyncOperation (#313)
Browse files Browse the repository at this point in the history
  • Loading branch information
halildurmus committed Jul 17, 2023
1 parent d8468ad commit a194214
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 8 deletions.
12 changes: 10 additions & 2 deletions packages/windows_foundation/lib/src/iasyncoperation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'dart:ffi';

import 'package:ffi/ffi.dart';
import 'package:win32/win32.dart';
import 'package:windows_ui/windows_ui.dart';

import '../internal.dart';
import 'exports.g.dart';
Expand All @@ -23,8 +24,8 @@ abstract interface class IAsyncOperation<TResult> extends IInspectable
/// Creates an instance of [IAsyncOperation] from the given `ptr`.
///
/// [TResult] must be of type `bool`, `Guid`, `int`, `Object?`, `String`,
/// `Uri?`, `IInspectable?` (e.g. `StorageFile?`) or `WinRTEnum` (e.g.
/// `LaunchUriStatus`).
/// `Uri?`, `IInspectable?` (e.g. `StorageFile?`), `WinRTEnum` (e.g.
/// `LaunchUriStatus`), or `WinRTStruct` (e.g. `LoadMoreItemsResult`).
///
/// [intType] must be specified if [TResult] is `int`.
/// ```dart
Expand Down Expand Up @@ -100,6 +101,13 @@ abstract interface class IAsyncOperation<TResult> extends IInspectable
return _IAsyncOperationWinRTEnum.fromPtr(ptr, enumCreator: enumCreator);
}

if (isSubtypeOfWinRTStruct<TResult>()) {
if (TResult == LoadMoreItemsResult) {
return _IAsyncOperationLoadMoreItemsResult.fromPtr(ptr)
as IAsyncOperation<TResult>;
}
}

throw ArgumentError.value(TResult, 'TResult', 'Unsupported type');
}

Expand Down
32 changes: 32 additions & 0 deletions packages/windows_foundation/lib/src/iasyncoperation_part.dart
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,38 @@ final class _IAsyncOperationInt64 extends IAsyncOperation<int> {
}
}

final class _IAsyncOperationLoadMoreItemsResult
extends IAsyncOperation<LoadMoreItemsResult> {
_IAsyncOperationLoadMoreItemsResult.fromPtr(super.ptr);

@override
LoadMoreItemsResult getResults() {
final retValuePtr = calloc<NativeLoadMoreItemsResult>();

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

if (FAILED(hr)) throwWindowsException(hr);

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

final class _IAsyncOperationInspectable<TResult>
extends IAsyncOperation<TResult> {
_IAsyncOperationInspectable.fromPtr(super.ptr, {required this.creator});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,12 @@ final class NativeHolographicStereoTransform extends Struct {
external NativeMatrix4x4 right;
}

/// @nodoc
final class NativeLoadMoreItemsResult extends Struct {
@Uint32()
external int count;
}

/// @nodoc
final class NativeMatrix3x2 extends Struct {
@Float()
Expand Down
1 change: 1 addition & 0 deletions packages/windows_ui/lib/src/exports.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,4 @@ export 'windowmanagement/idisplayregion.dart';
export 'windowmanagement/iwindowingenvironment.dart';
export 'windowmanagement/windowingenvironment.dart';
export 'windowmanagement/windowingenvironmentkind.dart';
export 'xaml/data/loadmoreitemsresult.dart';
53 changes: 53 additions & 0 deletions packages/windows_ui/lib/src/xaml/data/loadmoreitemsresult.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (c) 2023, Dart | Windows. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// THIS FILE IS GENERATED AUTOMATICALLY AND SHOULD NOT BE EDITED DIRECTLY.

import 'dart:ffi';

import 'package:ffi/ffi.dart';
import 'package:windows_foundation/internal.dart';
import 'package:windows_foundation/windows_foundation.dart';

/// Wraps the asynchronous results of a LoadMoreItemsAsync call.
final class LoadMoreItemsResult implements WinRTStruct {
LoadMoreItemsResult(this.count);

final int count;

@override
Pointer<NativeLoadMoreItemsResult> toNative({Allocator allocator = malloc}) {
final nativeStructPtr = allocator<NativeLoadMoreItemsResult>();
nativeStructPtr.ref..count = count;
return nativeStructPtr;
}

@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is LoadMoreItemsResult && count == other.count;
}

@override
int get hashCode => count.hashCode;
}

/// @nodoc
extension PointerNativeLoadMoreItemsResultConversion
on Pointer<NativeLoadMoreItemsResult> {
/// Converts this [NativeLoadMoreItemsResult] to a Dart
/// [LoadMoreItemsResult].
LoadMoreItemsResult toDart() {
final ref = this.ref;
return LoadMoreItemsResult(ref.count);
}

/// Creates a `List<LoadMoreItemsResult>` from
/// `Pointer<NativeLoadMoreItemsResult>`.
///
/// [length] must not be greater than the number of elements stored inside the
/// `Pointer<NativeLoadMoreItemsResult>`.
List<LoadMoreItemsResult> toList({int length = 1}) =>
[for (var i = 0; i < length; i++) elementAt(i).toDart()];
}
3 changes: 2 additions & 1 deletion packages/winrtgen/data/structs.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,6 @@
"Windows.UI.Color": "Describes a color in terms of alpha, red, green, and blue channels.",
"Windows.UI.UIAutomation.Core.AutomationAnnotationTypeRegistration": "Represents an annotation registration.",
"Windows.UI.UIAutomation.Core.AutomationRemoteOperationOperandId": "Represents an identifier that refers to an operand register of a CoreAutomationRemoteOperation.",
"Windows.UI.WindowId": "Defines an identifier for a top-level window."
"Windows.UI.WindowId": "Defines an identifier for a top-level window.",
"Windows.UI.Xaml.Data.LoadMoreItemsResult": "Wraps the asynchronous results of a LoadMoreItemsAsync call."
}
11 changes: 6 additions & 5 deletions packages/winrtgen/lib/src/constants/generic_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ const genericTypes = <GenericType>[

/// The type argument kinds for `IAsyncOperation`.
const _asyncOperationTypeArgKinds = <TypeArgKind>[
TypeArgKind.bool_, TypeArgKind.guid, TypeArgKind.int16, TypeArgKind.int32,
TypeArgKind.int64, TypeArgKind.nullableInspectable, //
TypeArgKind.nullableObject, TypeArgKind.nullableUri, TypeArgKind.string, //
TypeArgKind.uint8, TypeArgKind.uint16, TypeArgKind.uint32, //
TypeArgKind.uint64, TypeArgKind.winrtEnum, TypeArgKind.winrtFlagsEnum //
TypeArgKind.bool_, TypeArgKind.guid, TypeArgKind.int16, TypeArgKind.int32, //
TypeArgKind.int64, TypeArgKind.loadMoreItemsResult, //
TypeArgKind.nullableInspectable, TypeArgKind.nullableObject, //
TypeArgKind.nullableUri, TypeArgKind.string, TypeArgKind.uint8, //
TypeArgKind.uint16, TypeArgKind.uint32, TypeArgKind.uint64, //
TypeArgKind.winrtEnum, TypeArgKind.winrtFlagsEnum
];

/// The common type argument kind pairs for `IKeyValuePair`, `IMap`, and
Expand Down
3 changes: 3 additions & 0 deletions packages/winrtgen/lib/src/models/type_arg_kind.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ enum TypeArgKind {
int16('Int16'),
int32('Int32'),
int64('Int64'),
loadMoreItemsResult('LoadMoreItemsResult'),
mediaTimeRange('MediaTimeRange'),
mseTimeRange('MseTimeRange'),
nitRange('NitRange'),
Expand Down Expand Up @@ -173,6 +174,8 @@ enum TypeArgKind {
TypeArgKind.int64 ||
TypeArgKind.nullableInt64 =>
const TypeIdentifier(BaseType.int64Type),
TypeArgKind.loadMoreItemsResult => _createClassTypeIdentifier(
'Windows.UI.Xaml.Data.LoadMoreItemsResult'),
TypeArgKind.mediaTimeRange =>
_createClassTypeIdentifier('Windows.Media.MediaTimeRange'),
TypeArgKind.mseTimeRange ||
Expand Down

0 comments on commit a194214

Please sign in to comment.