Another try: NotifySignal activation simplification

This commit is contained in:
Michael Lamers 2018-08-05 00:06:12 +02:00 committed by Paul Knopf
parent 37fee9b2aa
commit 9f3e1343b7
2 changed files with 143 additions and 1 deletions

View file

@ -31,6 +31,47 @@ namespace Qml.Net.Tests.Qml
{
}
private string _someStringPropertyValue = "";
[NotifySignal]
public string SomeStringProperty
{
get => _someStringPropertyValue;
set {
if (_someStringPropertyValue == value)
return;
_someStringPropertyValue = value;
this.ActivateNotifySignal();
}
}
private int _someIntPropertyValue = 0;
[NotifySignal("someWeirdSignalName")]
public int SomeIntProperty
{
get => _someIntPropertyValue;
set {
if (_someIntPropertyValue == value)
return;
_someIntPropertyValue = value;
this.ActivateNotifySignal();
}
}
private bool _someBoolPropertyValue = false;
public bool SomeBoolProperty
{
get => _someBoolPropertyValue;
set {
if (_someBoolPropertyValue == value)
return;
_someBoolPropertyValue = value;
this.ActivateNotifySignal();
}
}
}
[Signal("testSignal")]
@ -153,6 +194,75 @@ namespace Qml.Net.Tests.Qml
Mock.VerifySet(x => x.SignalRaised = true, Times.Once);
}
[Fact]
public void Can_raise_changed_default_signal_from_net()
{
Mock.Setup(x => x.SignalRaised).Returns(false);
NetTestHelper.RunQml(qmlApplicationEngine,
@"
import QtQuick 2.0
import tests 1.0
ObjectTestsQml {
id: test
Component.onCompleted: function() {
test.someStringPropertyChanged.connect(function() {
test.signalRaised = true
})
test.someStringProperty = 'NewValue'
}
}
");
Mock.VerifySet(x => x.SignalRaised = true, Times.Once);
}
[Fact]
public void Can_raise_changed_custom_signal_from_net()
{
Mock.Setup(x => x.SignalRaised).Returns(false);
NetTestHelper.RunQml(qmlApplicationEngine,
@"
import QtQuick 2.0
import tests 1.0
ObjectTestsQml {
id: test
Component.onCompleted: function() {
test.someWeirdSignalName.connect(function() {
test.signalRaised = true
})
test.someIntProperty = 1
}
}
");
Mock.VerifySet(x => x.SignalRaised = true, Times.Once);
}
[Fact]
public void Can_not_raise_invalid_changed_signal_from_net()
{
Mock.Setup(x => x.SignalRaised).Returns(false);
NetTestHelper.RunQml(qmlApplicationEngine,
@"
import QtQuick 2.0
import tests 1.0
ObjectTestsQml {
id: test
Component.onCompleted: function() {
test.someBoolPropertyChanged.connect(function() {
test.signalRaised = true
})
test.someBoolProperty = true
}
}
");
Mock.VerifySet(x => x.SignalRaised = true, Times.Never);
}
[Fact]
public void Can_raise_signal_from_net_with_args()
{

View file

@ -1,4 +1,7 @@
using Qml.Net.Internal;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using Qml.Net.Internal;
using Qml.Net.Internal.Types;
namespace Qml.Net
@ -34,6 +37,35 @@ namespace Qml.Net
return true;
}
/// <summary>
/// Activates the signal that has been attached to the given property using NotifySignalAttribute
/// </summary>
/// <param name="instance">object instance having the property the changed signal has to be activated for</param>
/// <param name="propertyName">
/// name of the property. Gets automatically filled with the caller member name.
/// So calling it directly out of the property that is tied to the signal doesn't need to set this parameter explicitly.</param>
/// <returns>true when the signal has been activated, otherwise false</returns>
public static bool ActivateNotifySignal(this object instance, [CallerMemberName] string propertyName = "")
{
if (instance == null)
return false;
var propertyInfo =
instance.GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public);
if (propertyInfo == null)
return false;
var notifySignalAttributes = propertyInfo.GetCustomAttributes().OfType<NotifySignalAttribute>();
var notifySignalAttribute = notifySignalAttributes.FirstOrDefault();
if (notifySignalAttribute == null)
return false;
var signalName = notifySignalAttribute.Name;
if (string.IsNullOrEmpty(signalName))
{
signalName = $"{propertyInfo.Name}Changed";
signalName = char.ToLower(signalName[0]) + signalName.Substring(1);
}
return ActivateSignal(instance, signalName);
}
public static void AttachToSignal(this object instance, string signalName, System.Delegate del)
{
instance.AttachDelegateToSignal(signalName, del);