diff options
| author | Miguel Costa <miguel.costa@qt.io> | 2025-10-26 17:44:58 +0100 |
|---|---|---|
| committer | Miguel Costa <miguel.costa@qt.io> | 2025-11-11 12:54:32 +0000 |
| commit | cf4d46797a1f65fe6f4451f19dda4f060842cd21 (patch) | |
| tree | 0d4c280dafbf1a365276c97f9bcc8a2ce9da1ae7 | |
| parent | ec068d1638be8cdfc072f5e352f2cf83d0e6c900 (diff) | |
Allow type casting in QML
Using the TypeCast object allows casting objects as other reference
types. TypeCast defines one cast function per generated reference type.
Change-Id: Id99fe82e9f94ab63c237bbc68caef72867a15e2f
Reviewed-by: Karsten Heimrich <karsten.heimrich@qt.io>
3 files changed, 75 insertions, 2 deletions
diff --git a/src/Qt.DotNet.Adapter/Qt/DotNet/TypeCast.cs b/src/Qt.DotNet.Adapter/Qt/DotNet/TypeCast.cs new file mode 100644 index 0000000..6e4cc32 --- /dev/null +++ b/src/Qt.DotNet.Adapter/Qt/DotNet/TypeCast.cs @@ -0,0 +1,18 @@ +/*************************************************************************************************** + Copyright (C) 2025 The Qt Company Ltd. + SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +***************************************************************************************************/ + +using System; +using Qt.Quick; + +namespace Qt.DotNet +{ + [Include] + [QmlElement(Singleton = true)] + public class TypeCast + { + [Include] + public TypeCast() { } + } +} diff --git a/src/Qt.DotNet.GenerationRules/Qt/DotNet/CodeGeneration/Rules/TypeCasting/GenerateTypeCast.cs b/src/Qt.DotNet.GenerationRules/Qt/DotNet/CodeGeneration/Rules/TypeCasting/GenerateTypeCast.cs new file mode 100644 index 0000000..af59fdd --- /dev/null +++ b/src/Qt.DotNet.GenerationRules/Qt/DotNet/CodeGeneration/Rules/TypeCasting/GenerateTypeCast.cs @@ -0,0 +1,53 @@ +/*************************************************************************************************** + Copyright (C) 2025 The Qt Company Ltd. + SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +***************************************************************************************************/ + +using System.Reflection; + +namespace Qt.DotNet.CodeGeneration.Rules.TypeCasting +{ + using static Placeholders; + using static Traits; + + public class GenerateTypeCast : Class.GenerateClass + { + public override bool Matches(MemberInfo src) + => base.Matches(src) && src != TypeOf<TypeCast>(); + public override IEnumerable<MemberInfo> DependsOn => [TypeOf<TypeCast>()]; + public override Result Execute(MemberInfo src) + { + if (src is not Type type) + return Error(); + + var typeCast = TypeOf<TypeCast>(); + + // TO-DO: Generate unique names for cast functions + + //////////////////////////////////////////////////////////////////////////////////////// + // + if (typeCast.GetPlaceholder(MethodDeclarations) is not { } methods) + return Error(); + methods += $@" +Q_INVOKABLE {type.MFn(Ns | Name)} *as{type.MFn(Name)}(QObject *obj); +{Blank}"; + //////////////////////////////////////////////////////////////////////////////////////// + // + if (typeCast.GetPlaceholder(Includes) is not { } includes) + return Error(); + includes += $"#include <{type.MFn(Ns | Dir)}{type.MFn(File)}.h>"; + + //////////////////////////////////////////////////////////////////////////////////////// + // + if (typeCast.GetPlaceholder(MethodsImplementation) is not { } implementation) + return Error(); + implementation += $@" +{type.MFn(Ns | Name)} *{typeCast.MFn(Ns | Name)}::as{type.MFn(Name)}(QObject *qObj) +{{ + return Convert::as<{type.MFn(Ns | Name)}>(qObj); +}} +{Blank}"; + return Ok; + } + } +} diff --git a/src/Qt.DotNet.Generator/Qt/DotNet/CodeGeneration/DependencyGraph.cs b/src/Qt.DotNet.Generator/Qt/DotNet/CodeGeneration/DependencyGraph.cs index 85b1ee5..97788b6 100644 --- a/src/Qt.DotNet.Generator/Qt/DotNet/CodeGeneration/DependencyGraph.cs +++ b/src/Qt.DotNet.Generator/Qt/DotNet/CodeGeneration/DependencyGraph.cs @@ -257,9 +257,11 @@ namespace Qt.DotNet.CodeGeneration } } - await Task.WhenAll( - assembly.ExportedTypes + var exportedTypes = assembly.ExportedTypes .Where(x => x.DeclaringType == null) + .Append(TypeOf<TypeCast>()); + + await Task.WhenAll(exportedTypes .Select(x => Task.Run(async () => await AddEdgeAsync(Root, x)))); if (!Edges.Any()) |
