Added supprot for setting/getting context properties.

This commit is contained in:
Paul Knopf 2018-09-23 18:21:48 -04:00
parent 65626d5a55
commit bf4abef06e
6 changed files with 155 additions and 46 deletions

View file

@ -153,52 +153,7 @@ void NetValueTypePacker::unpack(QSharedPointer<NetVariant> destination, void* so
break;
}
switch(sourceVariant->type()) {
case QVariant::Invalid:
destination->clear();
break;
case QVariant::Bool:
destination->setBool(sourceVariant->value<bool>());
break;
case QVariant::Char:
destination->setChar(sourceVariant->toChar());
break;
case QVariant::Int:
destination->setInt(sourceVariant->value<int>());
break;
case QVariant::UInt:
destination->setUInt(sourceVariant->value<unsigned int>());
break;
case QVariant::Double:
destination->setDouble(sourceVariant->value<double>());
break;
case QVariant::String:
{
QString stringValue = sourceVariant->toString();
destination->setString(&stringValue);
break;
}
case QVariant::DateTime:
{
QDateTime dateTimeValue = sourceVariant->toDateTime();
destination->setDateTime(dateTimeValue);
break;
}
default:
if(sourceVariant->userType() == qMetaTypeId<QJSValue>()) {
// TODO: Either serialize this type to a string, to be deserialized in .NET, or
// pass raw value to .NET to be dynamically invoked (using dynamic).
// See qtdeclarative\src\plugins\qmltooling\qmldbg_debugger\qqmlenginedebugservice.cpp:184
// for serialization methods.
QSharedPointer<NetJSValue> netJsValue = QSharedPointer<NetJSValue>(new NetJSValue(sourceVariant->value<QJSValue>()));
destination->setJsValue(netJsValue);
break;
}
qDebug() << "Unsupported variant type: " << sourceVariant->type();
break;
}
NetVariant::fromQVariant(sourceVariant, destination);
}
class StringValueTypePacker : public NetValueTypePacker

View file

@ -253,6 +253,72 @@ QJSValue NetVariant::toQJSValue(QJSEngine* jsEngine)
}
}
void NetVariant::fromQVariant(const QVariant* variant, QSharedPointer<NetVariant> destination)
{
switch(variant->type()) {
case QVariant::Invalid:
destination->clear();
break;
case QVariant::Bool:
destination->setBool(variant->value<bool>());
break;
case QVariant::Char:
destination->setChar(variant->toChar());
break;
case QVariant::Int:
destination->setInt(variant->value<int>());
break;
case QVariant::UInt:
destination->setUInt(variant->value<unsigned int>());
break;
case QVariant::Double:
destination->setDouble(variant->value<double>());
break;
case QVariant::String:
{
QString stringValue = variant->toString();
destination->setString(&stringValue);
break;
}
case QVariant::DateTime:
{
QDateTime dateTimeValue = variant->toDateTime();
destination->setDateTime(dateTimeValue);
break;
}
default:
if(variant->userType() == qMetaTypeId<QJSValue>()) {
// TODO: Either serialize this type to a string, to be deserialized in .NET, or
// pass raw value to .NET to be dynamically invoked (using dynamic).
// See qtdeclarative\src\plugins\qmltooling\qmldbg_debugger\qqmlenginedebugservice.cpp:184
// for serialization methods.
QSharedPointer<NetJSValue> netJsValue = QSharedPointer<NetJSValue>(new NetJSValue(variant->value<QJSValue>()));
destination->setJsValue(netJsValue);
break;
}
if(variant->userType() == QMetaType::QObjectStar) {
QObject* value = variant->value<QObject*>();
NetValueInterface* netValue = qobject_cast<NetValueInterface*>(value);
if(netValue) {
destination->setNetReference(netValue->getNetReference());
break;
}
}
qDebug() << "Unsupported variant type: " << variant->type();
break;
}
}
QSharedPointer<NetVariant> NetVariant::fromQVariant(const QVariant* variant)
{
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
fromQVariant(variant, result);
return result;
}
QVariant NetVariant::toQVariant()
{
QVariant result;

View file

@ -34,6 +34,8 @@ public:
void clear();
static QSharedPointer<NetVariant> fromQJSValue(const QJSValue& qJsValue);
QJSValue toQJSValue(QJSEngine* jsEngine);
static void fromQVariant(const QVariant* variant, QSharedPointer<NetVariant> destination);
static QSharedPointer<NetVariant> fromQVariant(const QVariant* variant);
QVariant toQVariant();
QString getDisplayValue();
private:

View file

@ -198,4 +198,22 @@ Q_DECL_EXPORT QQmlApplicationEngine* qqmlapplicationengine_internalPointer(QQmlA
return container->qmlEngine;
}
Q_DECL_EXPORT NetVariantContainer* qqmlapplicationengine_getContextProperty(QQmlApplicationEngineContainer* container, LPWCSTR name)
{
QVariant result = container->qmlEngine->rootContext()->contextProperty(QString::fromUtf16(name));
return new NetVariantContainer {
NetVariant::fromQVariant(&result)
};
}
Q_DECL_EXPORT void qqmlapplicationengine_setContextProperty(QQmlApplicationEngineContainer* container, LPWCSTR name, NetVariantContainer* valueContainer)
{
if(valueContainer == nullptr) {
container->qmlEngine->rootContext()->setContextProperty(QString::fromUtf16(name), nullptr);
} else {
QSharedPointer<NetVariant> value = valueContainer->variant;
container->qmlEngine->rootContext()->setContextProperty(QString::fromUtf16(name), value->toQVariant());
}
}
}

View file

@ -0,0 +1,29 @@
using System;
using FluentAssertions;
using Xunit;
namespace Qml.Net.Tests.Qml
{
public class QQmlApplicationEngineTests : BaseQmlTests<QQmlApplicationEngineTests.QQmlApplicationEngineQml>
{
public class QQmlApplicationEngineQml
{
public Guid Guid { get; set; }
}
[Fact]
public void Can_set_context_property()
{
var propName = Guid.NewGuid().ToString().Replace("-", "");
qmlApplicationEngine.GetContextProperty(propName).Should().BeNull();
qmlApplicationEngine.SetContextProperty(propName, 2);
qmlApplicationEngine.GetContextProperty(propName).Should().Be(2);
qmlApplicationEngine.SetContextProperty(propName, null);
qmlApplicationEngine.GetContextProperty(propName).Should().BeNull();
var o = new QQmlApplicationEngineQml();
o.Guid = Guid.NewGuid();
qmlApplicationEngine.SetContextProperty(propName, o);
((QQmlApplicationEngineQml) qmlApplicationEngine.GetContextProperty(propName)).Guid.Should().Be(o.Guid);
}
}
}

View file

@ -3,6 +3,7 @@ using System.Runtime.InteropServices;
using AdvancedDLSupport;
using Qml.Net.Internal;
using Qml.Net.Internal.Behaviors;
using Qml.Net.Internal.Qml;
using Qml.Net.Internal.Types;
namespace Qml.Net
@ -35,6 +36,38 @@ namespace Qml.Net
{
Interop.QQmlApplicationEngine.AddImportPath(Handle, path);
}
public object GetContextProperty(string name)
{
var result = Interop.QQmlApplicationEngine.GetContextProperty(Handle, name);
if (result == IntPtr.Zero)
{
return null;
}
using (var variant = new NetVariant(result))
{
object r = null;
Helpers.Unpackvalue(ref r, variant);
return r;
}
}
public void SetContextProperty(string name, object value)
{
if (value == null)
{
Interop.QQmlApplicationEngine.SetContextProperty(Handle, name, IntPtr.Zero);
}
else
{
using (var variant = new NetVariant())
{
Helpers.PackValue(value, variant);
Interop.QQmlApplicationEngine.SetContextProperty(Handle, name, variant.Handle);
}
}
}
internal IntPtr InternalPointer => Interop.QQmlApplicationEngine.InternalPointer(Handle);
@ -90,5 +123,11 @@ namespace Qml.Net
[NativeSymbol(Entrypoint = "qqmlapplicationengine_internalPointer")]
IntPtr InternalPointer(IntPtr app);
[NativeSymbol(Entrypoint = "qqmlapplicationengine_getContextProperty")]
IntPtr GetContextProperty(IntPtr app, [MarshalAs(UnmanagedType.LPWStr), CallerFree]string name);
[NativeSymbol(Entrypoint = "qqmlapplicationengine_setContextProperty")]
void SetContextProperty(IntPtr app, [MarshalAs(UnmanagedType.LPWStr), CallerFree]string path, IntPtr value);
}
}