Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make activation factories not weak and reduce duplicate retrieval of activation factories #1021

Merged
merged 4 commits into from
Oct 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions src/WinRT.Runtime/Projections/DataErrorsChangedEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal unsafe struct IDataErrorsChangedEventArgsVftbl

[global::WinRT.ObjectReferenceWrapper(nameof(_obj))]
[Guid("62D0BD1E-B85F-5FCC-842A-7CB0DDA37FE5")]
internal unsafe class WinRTDataErrorsChangedEventArgsRuntimeClassFactory
internal unsafe sealed class WinRTDataErrorsChangedEventArgsRuntimeClassFactory
{
[Guid("62D0BD1E-B85F-5FCC-842A-7CB0DDA37FE5")]
[StructLayout(LayoutKind.Sequential)]
Expand Down Expand Up @@ -74,13 +74,14 @@ namespace ABI.System.ComponentModel
[StructLayout(LayoutKind.Sequential)]
public unsafe struct DataErrorsChangedEventArgs
{
private static WeakLazy<ActivationFactory> _factory = new WeakLazy<ActivationFactory>();

private class ActivationFactory : BaseActivationFactory
private sealed class ActivationFactory : BaseActivationFactory
{
public ActivationFactory() : base("Microsoft.UI.Xaml.Data", "Microsoft.UI.Xaml.Data.DataErrorsChangedEventArgs")
{
}
}

internal static ABI.Microsoft.UI.Xaml.Data.WinRTDataErrorsChangedEventArgsRuntimeClassFactory Instance =
new ActivationFactory()._As<ABI.Microsoft.UI.Xaml.Data.WinRTDataErrorsChangedEventArgsRuntimeClassFactory.Vftbl>();
}

public static IObjectReference CreateMarshaler(global::System.ComponentModel.DataErrorsChangedEventArgs value)
Expand All @@ -90,8 +91,7 @@ public static IObjectReference CreateMarshaler(global::System.ComponentModel.Dat
return null;
}

ABI.Microsoft.UI.Xaml.Data.WinRTDataErrorsChangedEventArgsRuntimeClassFactory factory = _factory.Value._As<ABI.Microsoft.UI.Xaml.Data.WinRTDataErrorsChangedEventArgsRuntimeClassFactory.Vftbl>();
return factory.CreateInstance(value.PropertyName);
return ActivationFactory.Instance.CreateInstance(value.PropertyName);
}

public static IntPtr GetAbi(IObjectReference m) => m?.ThisPtr ?? IntPtr.Zero;
Expand Down Expand Up @@ -128,7 +128,8 @@ public static IntPtr FromManaged(global::System.ComponentModel.DataErrorsChanged
{
return IntPtr.Zero;
}
return CreateMarshaler(value).GetRef();
using var objRef = CreateMarshaler(value);
return objRef.GetRef();
}

public static void DisposeMarshaler(IObjectReference m) { m?.Dispose(); }
Expand Down
19 changes: 10 additions & 9 deletions src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace ABI.Microsoft.UI.Xaml.Interop
{
[global::WinRT.ObjectReferenceWrapper(nameof(_obj))]
[Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")]
internal unsafe class INotifyCollectionChangedEventArgs
internal sealed unsafe class INotifyCollectionChangedEventArgs
{
[Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")]
[StructLayout(LayoutKind.Sequential)]
Expand Down Expand Up @@ -110,7 +110,7 @@ public unsafe int OldStartingIndex

[global::WinRT.ObjectReferenceWrapper(nameof(_obj))]
[Guid("5108EBA4-4892-5A20-8374-A96815E0FD27")]
internal unsafe class WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory
internal unsafe sealed class WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory
{
[Guid("5108EBA4-4892-5A20-8374-A96815E0FD27")]
[StructLayout(LayoutKind.Sequential)]
Expand Down Expand Up @@ -167,13 +167,14 @@ namespace ABI.System.Collections.Specialized
[StructLayout(LayoutKind.Sequential)]
public struct NotifyCollectionChangedEventArgs
{
private static WeakLazy<ActivationFactory> _propertyChangedArgsFactory = new WeakLazy<ActivationFactory>();

private class ActivationFactory : BaseActivationFactory
private sealed class ActivationFactory : BaseActivationFactory
{
public ActivationFactory() : base("Microsoft.UI.Xaml.Interop", "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs")
{
}
}

internal static WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory Instance =
new ActivationFactory()._As<WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory.Vftbl>();
}

public static IObjectReference CreateMarshaler(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value)
Expand All @@ -183,8 +184,7 @@ public static IObjectReference CreateMarshaler(global::System.Collections.Specia
return null;
}

WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory factory = _propertyChangedArgsFactory.Value._As<WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory.Vftbl>();
return factory.CreateInstanceWithAllParameters(value.Action, value.NewItems, value.OldItems, value.NewStartingIndex, value.OldStartingIndex, null, out _);
return ActivationFactory.Instance.CreateInstanceWithAllParameters(value.Action, value.NewItems, value.OldItems, value.NewStartingIndex, value.OldStartingIndex, null, out _);
}

public static IntPtr GetAbi(IObjectReference m) => m?.ThisPtr ?? IntPtr.Zero;
Expand Down Expand Up @@ -228,7 +228,8 @@ public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCo
{
return IntPtr.Zero;
}
return CreateMarshaler(value).GetRef();
using var objRef = CreateMarshaler(value);
return objRef.GetRef();
}

public static void DisposeMarshaler(IObjectReference m) { m?.Dispose(); }
Expand Down
17 changes: 9 additions & 8 deletions src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ internal unsafe struct IPropertyChangedEventArgsVftbl

[global::WinRT.ObjectReferenceWrapper(nameof(_obj))]
[Guid("7C0C27A8-0B41-5070-B160-FC9AE960A36C")]
internal unsafe class WinRTPropertyChangedEventArgsRuntimeClassFactory
internal sealed unsafe class WinRTPropertyChangedEventArgsRuntimeClassFactory
{
[Guid("7C0C27A8-0B41-5070-B160-FC9AE960A36C")]
[StructLayout(LayoutKind.Sequential)]
Expand Down Expand Up @@ -75,13 +75,14 @@ namespace ABI.System.ComponentModel
[StructLayout(LayoutKind.Sequential)]
public unsafe struct PropertyChangedEventArgs
{
private static WeakLazy<ActivationFactory> _propertyChangedArgsFactory = new WeakLazy<ActivationFactory>();

private class ActivationFactory : BaseActivationFactory
private sealed class ActivationFactory : BaseActivationFactory
{
public ActivationFactory() : base("Microsoft.UI.Xaml.Data", "Microsoft.UI.Xaml.Data.PropertyChangedEventArgs")
{
}
}

internal static ABI.Microsoft.UI.Xaml.Data.WinRTPropertyChangedEventArgsRuntimeClassFactory Instance =
new ActivationFactory()._As<ABI.Microsoft.UI.Xaml.Data.WinRTPropertyChangedEventArgsRuntimeClassFactory.Vftbl>();
}

public static IObjectReference CreateMarshaler(global::System.ComponentModel.PropertyChangedEventArgs value)
Expand All @@ -91,8 +92,7 @@ public static IObjectReference CreateMarshaler(global::System.ComponentModel.Pro
return null;
}

ABI.Microsoft.UI.Xaml.Data.WinRTPropertyChangedEventArgsRuntimeClassFactory factory = _propertyChangedArgsFactory.Value._As<ABI.Microsoft.UI.Xaml.Data.WinRTPropertyChangedEventArgsRuntimeClassFactory.Vftbl>();
return factory.CreateInstance(value.PropertyName, null, out _);
return ActivationFactory.Instance.CreateInstance(value.PropertyName, null, out _);
}

public static IntPtr GetAbi(IObjectReference m) => m?.ThisPtr ?? IntPtr.Zero;
Expand Down Expand Up @@ -129,7 +129,8 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv
{
return IntPtr.Zero;
}
return CreateMarshaler(value).GetRef();
using var objRef = CreateMarshaler(value);
return objRef.GetRef();
}

public static void DisposeMarshaler(IObjectReference m) { m?.Dispose(); }
Expand Down
17 changes: 9 additions & 8 deletions src/WinRT.Runtime/Projections/Uri.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace ABI.System

[global::WinRT.ObjectReferenceWrapper(nameof(_obj))]
[Guid("44A9796F-723E-4FDF-A218-033E75B0C084")]
internal class WinRTUriRuntimeClassFactory
internal sealed class WinRTUriRuntimeClassFactory
{
[Guid("44A9796F-723E-4FDF-A218-033E75B0C084")]
[StructLayout(LayoutKind.Sequential)]
Expand Down Expand Up @@ -83,13 +83,14 @@ public unsafe IObjectReference CreateUri(string uri)
[StructLayout(LayoutKind.Sequential)]
public unsafe struct Uri
{
private static WeakLazy<ActivationFactory> _uriActivationFactory = new WeakLazy<ActivationFactory>();

private class ActivationFactory : BaseActivationFactory
private sealed class ActivationFactory : BaseActivationFactory
{
public ActivationFactory() : base("Windows.Foundation", "Windows.Foundation.Uri")
{
}
}

internal static WinRTUriRuntimeClassFactory Instance =
new ActivationFactory()._As<WinRTUriRuntimeClassFactory.Vftbl>();
}

public static IObjectReference CreateMarshaler(global::System.Uri value)
Expand All @@ -99,8 +100,7 @@ public static IObjectReference CreateMarshaler(global::System.Uri value)
return null;
}

WinRTUriRuntimeClassFactory factory = _uriActivationFactory.Value._As<WinRTUriRuntimeClassFactory.Vftbl>();
return factory.CreateUri(value.OriginalString);
return ActivationFactory.Instance.CreateUri(value.OriginalString);
}

public static IntPtr GetAbi(IObjectReference m) => m?.ThisPtr ?? IntPtr.Zero;
Expand Down Expand Up @@ -137,7 +137,8 @@ public static IntPtr FromManaged(global::System.Uri value)
{
return IntPtr.Zero;
}
return CreateMarshaler(value).GetRef();
using var objRef = CreateMarshaler(value);
return objRef.GetRef();
}

public static void DisposeMarshaler(IObjectReference m) { m?.Dispose(); }
Expand Down
77 changes: 43 additions & 34 deletions src/cswinrt/code_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -1628,26 +1628,24 @@ remove => %.% -= value;

std::string write_static_cache_object(writer& w, std::string_view cache_type_name, TypeDef const& class_type)
{
bool hasStaticEvent = false;
for (auto&& evt : class_type.EventList())
{
auto [add, _] = get_event_methods(evt);
if (add.Flags().Static())
{
hasStaticEvent = true;
break;
}
}

auto instance = hasStaticEvent ?
auto instance =
w.write_temp(
"private static readonly _% _instance = new _%();",
cache_type_name,
cache_type_name) :
w.write_temp(
"private static readonly WeakLazy<_%> _instance = new WeakLazy<_%>();",
cache_type_name,
cache_type_name);
auto factoryAs = w.write_temp("%",
bind([&](writer& w)
{
if (is_static(class_type))
{
w.write("_factory._As");
}
else
{
w.write("ActivationFactory<%>.As", class_type.TypeName());
}
})
);

if (settings.netstandard_compat)
{
Expand All @@ -1656,14 +1654,15 @@ remove => %.% -= value;
cache_type_name);
auto cache_interface =
w.write_temp(
R"(_factory._As<%>)",
R"(%<%>)",
factoryAs,
cache_vftbl_type);
w.write(R"(
internal class _% : ABI.%.%
{
public _%() : base(%()) { }
%
internal static % Instance => %;
internal static % Instance => _instance;
}
)",
cache_type_name,
Expand All @@ -1672,8 +1671,7 @@ internal static % Instance => %;
cache_type_name,
cache_interface,
instance,
cache_type_name,
hasStaticEvent ? "_instance" : "_instance.Value");
cache_type_name);
}
else
{
Expand All @@ -1683,11 +1681,11 @@ internal class _% : IWinRTObject
private IObjectReference _obj;
public _%()
{
_obj = _factory._As(GuidGenerator.GetIID(typeof(%.%).GetHelperType()));
_obj = %(GuidGenerator.GetIID(typeof(%.%).GetHelperType()));
}

%
internal static % Instance => (%)%;
internal static % Instance => (%)_instance;

IObjectReference IWinRTObject.NativeObject => _obj;
bool IWinRTObject.HasUnwrappableNativeObject => false;
Expand All @@ -1699,12 +1697,12 @@ global::System.Collections.Concurrent.ConcurrentDictionary<global::System.Runtim
)",
cache_type_name,
cache_type_name,
factoryAs,
class_type.TypeNamespace(),
cache_type_name,
instance,
cache_type_name,
cache_type_name,
hasStaticEvent ? "_instance" : "_instance.Value");
cache_type_name);
}

return w.write_temp("_%.Instance", cache_type_name);
Expand Down Expand Up @@ -1938,15 +1936,26 @@ Marshal.Release(inner);
});
}

w.write(R"(
if (is_static(type))
{
w.write(R"(
internal static %BaseActivationFactory _factory = new BaseActivationFactory("%", "%.%");
public static %I As<I>() => _factory.AsInterface<I>();
)",
has_base_factory ? "new " : "",
type.TypeNamespace(),
type.TypeNamespace(),
type.TypeName(),
has_base_factory ? "new " : "");
has_base_factory ? "new " : "",
type.TypeNamespace(),
type.TypeNamespace(),
type.TypeName(),
has_base_factory ? "new " : "");
}
else
{
w.write(R"(
public static %I As<I>() => ActivationFactory<%>.AsInterface<I>();
)",
has_base_factory ? "new " : "",
type.TypeName());
}
}

write_static_members(w, factory.type, type);
Expand Down Expand Up @@ -3332,8 +3341,8 @@ public unsafe % %(%)
internal class _% : ABI.%.%
{
public _%() : base(%()) { }
private static WeakLazy<_%> _instance = new WeakLazy<_%>();
internal static _% Instance => _instance.Value;
private static _% _instance = new _%();
internal static _% Instance => _instance;
%
}
)",
Expand All @@ -3360,8 +3369,8 @@ public _%()
_obj = ActivationFactory<%>.As(GuidGenerator.GetIID(typeof(%.%).GetHelperType()));
}

private static WeakLazy<_%> _instance = new WeakLazy<_%>();
internal static _% Instance => _instance.Value;
private static _% _instance = new _%();
internal static _% Instance => _instance;

IObjectReference IWinRTObject.NativeObject => _obj;
bool IWinRTObject.HasUnwrappableNativeObject => false;
Expand Down
Loading