diff --git a/src/native/QmlNet/QmlNet/qml/JsNetObject.cpp b/src/native/QmlNet/QmlNet/qml/JsNetObject.cpp index f535e781..cfcd436a 100644 --- a/src/native/QmlNet/QmlNet/qml/JsNetObject.cpp +++ b/src/native/QmlNet/QmlNet/qml/JsNetObject.cpp @@ -260,8 +260,8 @@ ReturnedValue NetObject::method_toJsArray(const FunctionObject *b, const Value * } QSharedPointer netReference = value->getNetReference(); - if(!netReference->getTypeInfo()->isArray()) { - THROW_GENERIC_ERROR("Net.toJsArray(): Parameter is not a .NET array"); + if(!netReference->getTypeInfo()->isArray() && !netReference->getTypeInfo()->isList()) { + THROW_GENERIC_ERROR("Net.toJsArray(): Parameter is not a type that can be wrapped on a JavaScript list."); } return NetArray::create(scope.engine, NetValue::forInstance(netReference)); diff --git a/src/native/QmlNet/QmlNet/qml/NetValueMetaObject.cpp b/src/native/QmlNet/QmlNet/qml/NetValueMetaObject.cpp index 96c091a0..d46632ce 100644 --- a/src/native/QmlNet/QmlNet/qml/NetValueMetaObject.cpp +++ b/src/native/QmlNet/QmlNet/qml/NetValueMetaObject.cpp @@ -112,7 +112,7 @@ int NetValueMetaObject::metaCall(QMetaObject::Call c, int idx, void **a) QSharedPointer propertyType = propertyInfo->getReturnType(); QSharedPointer result = QSharedPointer(new NetVariant()); - readProperty(propertyInfo, instance, result); + readProperty(propertyInfo, instance, nullptr, result); NetMetaValuePack(propertyType->getPrefVariantType(), result, a[0]); } @@ -130,7 +130,7 @@ int NetValueMetaObject::metaCall(QMetaObject::Call c, int idx, void **a) QSharedPointer newValue = QSharedPointer(new NetVariant()); NetMetaValueUnpack(propertyType->getPrefVariantType(), newValue, a[0]); - writeProperty(propertyInfo, instance, newValue); + writeProperty(propertyInfo, instance, nullptr, newValue); } break; case InvokeMetaMethod: diff --git a/src/native/QmlNet/QmlNet/types/Callbacks.cpp b/src/native/QmlNet/QmlNet/types/Callbacks.cpp index 744d497d..3cfed3d2 100644 --- a/src/native/QmlNet/QmlNet/types/Callbacks.cpp +++ b/src/native/QmlNet/QmlNet/types/Callbacks.cpp @@ -6,8 +6,8 @@ typedef void (*loadTypeInfoCb)(NetTypeInfoContainer* typeInfo); typedef void (*releaseNetReferenceCb)(uint64_t objectId); typedef void (*releaseNetDelegateGCHandleCb)(NetGCHandle* handle); typedef NetReferenceContainer* (*instantiateTypeCb)(NetTypeInfoContainer* type); -typedef void (*readPropertyCb)(NetPropertyInfoContainer* property, NetReferenceContainer* target, NetVariantContainer* result); -typedef void (*writePropertyCb)(NetPropertyInfoContainer* property, NetReferenceContainer* target, NetVariantContainer* value); +typedef void (*readPropertyCb)(NetPropertyInfoContainer* property, NetReferenceContainer* target, NetVariantContainer* indexParameter, NetVariantContainer* result); +typedef void (*writePropertyCb)(NetPropertyInfoContainer* property, NetReferenceContainer* target, NetVariantContainer* indexParameter, NetVariantContainer* value); typedef void (*invokeMethodCb)(NetMethodInfoContainer* method, NetReferenceContainer* target, NetVariantListContainer* parameters, NetVariantContainer* result); typedef void (*gcCollectCb)(int maxGeneration); typedef bool (*raiseNetSignalsCb)(NetReferenceContainer* target, LPWCSTR signalName, NetVariantListContainer* parameters); @@ -76,25 +76,33 @@ QSharedPointer instantiateType(QSharedPointer type) { return result; } -void readProperty(QSharedPointer property, QSharedPointer target, QSharedPointer result) { +void readProperty(QSharedPointer property, QSharedPointer target, QSharedPointer indexParameter, QSharedPointer result) { NetPropertyInfoContainer* propertyContainer = new NetPropertyInfoContainer(); propertyContainer->property = property; NetReferenceContainer* targetContainer = new NetReferenceContainer(); targetContainer->instance = target; + NetVariantContainer* indexParameterContainer = nullptr; + if(indexParameter != nullptr) { + indexParameterContainer = new NetVariantContainer{indexParameter}; + } NetVariantContainer* valueContainer = new NetVariantContainer(); valueContainer->variant = result; - sharedCallbacks.readProperty(propertyContainer, targetContainer, valueContainer); + sharedCallbacks.readProperty(propertyContainer, targetContainer, indexParameterContainer, valueContainer); // The callbacks dispose of the types. } -void writeProperty(QSharedPointer property, QSharedPointer target, QSharedPointer value) { +void writeProperty(QSharedPointer property, QSharedPointer target, QSharedPointer indexParameter, QSharedPointer value) { NetPropertyInfoContainer* propertyContainer = new NetPropertyInfoContainer(); propertyContainer->property = property; NetReferenceContainer* targetContainer = new NetReferenceContainer(); targetContainer->instance = target; + NetVariantContainer* indexParameterContainer = nullptr; + if(indexParameter != nullptr) { + indexParameterContainer = new NetVariantContainer{indexParameter}; + } NetVariantContainer* resultContainer = new NetVariantContainer(); resultContainer->variant = value; - sharedCallbacks.writeProperty(propertyContainer, targetContainer, resultContainer); + sharedCallbacks.writeProperty(propertyContainer, targetContainer, indexParameterContainer, resultContainer); // The callbacks dispose of the types. } @@ -169,34 +177,6 @@ Q_DECL_EXPORT NetReferenceContainer* type_info_callbacks_instantiateType(NetType return sharedCallbacks.instantiateType(typeCopy); } -Q_DECL_EXPORT void type_info_callbacks_readProperty(NetPropertyInfoContainer* property, NetReferenceContainer* target, NetVariantContainer* result) { - // The parameters have to be copied to new containers, because the callback - // will delete them. - NetPropertyInfoContainer* propertyCopy = new NetPropertyInfoContainer{property->property}; - NetReferenceContainer* targetCopy = new NetReferenceContainer{target->instance}; - NetVariantContainer* resultCopy = nullptr; - - if(result != nullptr) { - resultCopy = new NetVariantContainer{result->variant}; - } - - sharedCallbacks.readProperty(propertyCopy, targetCopy, resultCopy); -} - -Q_DECL_EXPORT void type_info_callbacks_writeProperty(NetPropertyInfoContainer* property, NetReferenceContainer* target, NetVariantContainer* value) { - // The parameters have to be copied to new containers, because the callback - // will delete them. - NetPropertyInfoContainer* propertyCopy = new NetPropertyInfoContainer{property->property}; - NetReferenceContainer* targetCopy = new NetReferenceContainer{target->instance}; - NetVariantContainer* valueCopy = nullptr; - - if(value != nullptr) { - valueCopy = new NetVariantContainer{value->variant}; - } - - sharedCallbacks.writeProperty(propertyCopy, targetCopy, valueCopy); -} - Q_DECL_EXPORT void type_info_callbacks_invokeMethod(NetMethodInfoContainer* method, NetReferenceContainer* target, NetVariantListContainer* parameters, NetVariantContainer* result) { // The parameters have to be copied to new containers, because the callback // will delete them. diff --git a/src/native/QmlNet/QmlNet/types/Callbacks.h b/src/native/QmlNet/QmlNet/types/Callbacks.h index ed4d9da8..a1f11978 100644 --- a/src/native/QmlNet/QmlNet/types/Callbacks.h +++ b/src/native/QmlNet/QmlNet/types/Callbacks.h @@ -23,9 +23,9 @@ void loadTypeInfo(QSharedPointer typeInfo); QSharedPointer instantiateType(QSharedPointer type); -void readProperty(QSharedPointer property, QSharedPointer target, QSharedPointer result); +void readProperty(QSharedPointer property, QSharedPointer target, QSharedPointer indexParameter, QSharedPointer result); -void writeProperty(QSharedPointer property, QSharedPointer target, QSharedPointer value); +void writeProperty(QSharedPointer property, QSharedPointer target, QSharedPointer indexParameter, QSharedPointer value); void invokeNetMethod(QSharedPointer method, QSharedPointer target, QSharedPointer parameters, QSharedPointer result); diff --git a/src/native/QmlNet/QmlNet/types/NetTypeArrayFacade.cpp b/src/native/QmlNet/QmlNet/types/NetTypeArrayFacade.cpp index 607adac6..75e968cb 100644 --- a/src/native/QmlNet/QmlNet/types/NetTypeArrayFacade.cpp +++ b/src/native/QmlNet/QmlNet/types/NetTypeArrayFacade.cpp @@ -1,5 +1,6 @@ #include #include +#include #include NetTypeArrayFacade::NetTypeArrayFacade() @@ -17,6 +18,14 @@ QSharedPointer NetTypeArrayFacade::fromType(QSharedPointer(); } + if(type->isList()) { + QSharedPointer facade = QSharedPointer(new NetTypeArrayFacade_List(type)); + if(facade->isIncomplete()) { + return nullptr; + } + return facade.dynamicCast(); + } + return nullptr; } diff --git a/src/native/QmlNet/QmlNet/types/NetTypeArrayFacadeArray.cpp b/src/native/QmlNet/QmlNet/types/NetTypeArrayFacadeArray.cpp index 14df3ad7..9bf14bf1 100644 --- a/src/native/QmlNet/QmlNet/types/NetTypeArrayFacadeArray.cpp +++ b/src/native/QmlNet/QmlNet/types/NetTypeArrayFacadeArray.cpp @@ -47,7 +47,7 @@ bool NetTypeArrayFacade_Array::isFixed() uint NetTypeArrayFacade_Array::getLength(QSharedPointer reference) { QSharedPointer result = QSharedPointer(new NetVariant()); - readProperty(_lengthProperty, reference, result); + readProperty(_lengthProperty, reference, nullptr, result); return static_cast(result->getInt()); } diff --git a/src/native/QmlNet/QmlNet/types/NetTypeArrayFacadeList.cpp b/src/native/QmlNet/QmlNet/types/NetTypeArrayFacadeList.cpp new file mode 100644 index 00000000..d0a77ce1 --- /dev/null +++ b/src/native/QmlNet/QmlNet/types/NetTypeArrayFacadeList.cpp @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include +#include + +NetTypeArrayFacade_List::NetTypeArrayFacade_List(QSharedPointer type) : + _isIncomplete(false) +{ + for(int x = 0; x < type->getPropertyCount(); x++) { + QSharedPointer property = type->getProperty(x); + if(property->getPropertyName().compare("Count") == 0) { + _lengthProperty = property; + } else if(property->getPropertyName().compare("Item") == 0) { + _itemProperty = property; + } + } + + if(_lengthProperty == nullptr || + _itemProperty == nullptr) { + _isIncomplete = true; + return; + } +} + +bool NetTypeArrayFacade_List::isIncomplete() +{ + return _isIncomplete; +} + +bool NetTypeArrayFacade_List::isFixed() +{ + return false; +} + +uint NetTypeArrayFacade_List::getLength(QSharedPointer reference) +{ + QSharedPointer result = QSharedPointer(new NetVariant()); + readProperty(_lengthProperty, reference, nullptr, result); + return static_cast(result->getInt()); +} + +QSharedPointer NetTypeArrayFacade_List::getIndexed(QSharedPointer reference, int index) +{ + QSharedPointer result = QSharedPointer(new NetVariant()); + QSharedPointer indexParameter = QSharedPointer(new NetVariant()); + indexParameter->setInt(index); + readProperty(_itemProperty, reference, indexParameter, result); + return result; +} + +void NetTypeArrayFacade_List::setIndexed(QSharedPointer reference, int index, QSharedPointer value) +{ + QSharedPointer indexParameter = QSharedPointer(new NetVariant()); + indexParameter->setInt(index); + writeProperty(_itemProperty, reference, indexParameter, value); +} diff --git a/src/native/QmlNet/QmlNet/types/NetTypeArrayFacadeList.h b/src/native/QmlNet/QmlNet/types/NetTypeArrayFacadeList.h new file mode 100644 index 00000000..30470201 --- /dev/null +++ b/src/native/QmlNet/QmlNet/types/NetTypeArrayFacadeList.h @@ -0,0 +1,24 @@ +#ifndef NETTYPEARRAYFACADELIST_H +#define NETTYPEARRAYFACADELIST_H + +#include + +class NetMethodInfo; +class NetPropertyInfo; + +class NetTypeArrayFacade_List : public NetTypeArrayFacade +{ +public: + NetTypeArrayFacade_List(QSharedPointer type); + bool isIncomplete(); + bool isFixed(); + uint getLength(QSharedPointer reference); + QSharedPointer getIndexed(QSharedPointer reference, int index); + void setIndexed(QSharedPointer reference, int index, QSharedPointer value); +private: + bool _isIncomplete; + QSharedPointer _lengthProperty; + QSharedPointer _itemProperty; +}; + +#endif // NETTYPEARRAYFACADELIST_H diff --git a/src/native/QmlNet/QmlNet/types/types.pri b/src/native/QmlNet/QmlNet/types/types.pri index c16dfd50..cc7fde7c 100644 --- a/src/native/QmlNet/QmlNet/types/types.pri +++ b/src/native/QmlNet/QmlNet/types/types.pri @@ -8,7 +8,8 @@ SOURCES += \ $$PWD/NetSignalInfo.cpp \ $$PWD/NetDelegate.cpp \ $$PWD/NetTypeArrayFacade.cpp \ - $$PWD/NetTypeArrayFacadeArray.cpp + $$PWD/NetTypeArrayFacadeArray.cpp \ + $$PWD/NetTypeArrayFacadeList.cpp HEADERS += \ $$PWD/NetTypeInfo.h \ @@ -20,4 +21,5 @@ HEADERS += \ $$PWD/NetSignalInfo.h \ $$PWD/NetDelegate.h \ $$PWD/NetTypeArrayFacade.h \ - $$PWD/NetTypeArrayFacadeArray.h + $$PWD/NetTypeArrayFacadeArray.h \ + $$PWD/NetTypeArrayFacadeList.h diff --git a/src/net/Qml.Net.Tests/Qml/ArrayTests.cs b/src/net/Qml.Net.Tests/Qml/ArrayTests.cs index 754fcaf1..05511817 100644 --- a/src/net/Qml.Net.Tests/Qml/ArrayTests.cs +++ b/src/net/Qml.Net.Tests/Qml/ArrayTests.cs @@ -1,141 +1,214 @@ using System; +using System.Collections.Generic; using FluentAssertions; using Moq; using Xunit; namespace Qml.Net.Tests.Qml { - public class ArrayTests : BaseQmlTests + public class ArrayTests { - public class ArrayTestsQml + public class ArrayType : BaseQmlTests { - public virtual int[] GetArray() + public class ArrayTestsQml { - return null; - } + public virtual int[] GetArray() + { + return null; + } - public virtual void Test(object value) - { + public virtual void Test(object value) + { + } + } + + [Fact] + public void Can_get_length() + { + var array = new[] {3, 4, 6}; + Mock.Setup(x => x.GetArray()).Returns(array); + Mock.Setup(x => x.Test(3)); + + RunQmlTest( + "test", + @" + var array = Net.toJsArray(test.getArray()) + test.test(array.length) + "); + + Mock.Verify(x => x.GetArray(), Times.Once); + Mock.Verify(x => x.Test(3), Times.Once); + } + + [Fact] + public void Can_get_indexed() + { + var array = new[] {3, 4, 6}; + Mock.Setup(x => x.GetArray()).Returns(array); + Mock.Setup(x => x.Test(4)); + + RunQmlTest( + "test", + @" + var array = Net.toJsArray(test.getArray()) + test.test(array[1]) + "); + + Mock.Verify(x => x.GetArray(), Times.Once); + Mock.Verify(x => x.Test(4), Times.Once); + } + + [Fact] + public void Can_set_indexed() + { + var array = new[] {3, 4, 6}; + Mock.Setup(x => x.GetArray()).Returns(array); + + RunQmlTest( + "test", + @" + var array = Net.toJsArray(test.getArray()) + array[2] = 234 + "); + + Mock.Verify(x => x.GetArray(), Times.Once); + array[2].Should().Be(234); + } + + [Fact] + public void Can_forEach() + { + var array = new[] {3, 4, 7}; + Mock.Setup(x => x.GetArray()).Returns(array); + + RunQmlTest( + "test", + @" + var array = Net.toJsArray(test.getArray()) + array.forEach(function(value) { + test.test(value) + }) + "); + + Mock.Verify(x => x.GetArray(), Times.Once); + Mock.Verify(x => x.Test(3), Times.Once); + Mock.Verify(x => x.Test(4), Times.Once); + Mock.Verify(x => x.Test(7), Times.Once); + } + + [Fact] + public void Can_not_push_for_array() + { + var array = new[] {3, 4, 7}; + Mock.Setup(x => x.GetArray()).Returns(array); + Mock.Setup(x => x.Test(It.IsAny())); + + RunQmlTest( + "test", + @" + var array = Net.toJsArray(test.getArray()) + try { + array.push(23) + } catch(err) { + test.test(true) + } + "); + + Mock.Verify(x => x.GetArray(), Times.Once); + Mock.Verify(x => x.Test(true), Times.Once); + } + + [Fact] + public void Can_not_pop_for_array() + { + var array = new[] {3, 4, 7}; + Mock.Setup(x => x.GetArray()).Returns(array); + Mock.Setup(x => x.Test(It.IsAny())); + + RunQmlTest( + "test", + @" + var array = Net.toJsArray(test.getArray()) + try { + array.pop() + } catch(err) { + test.test(true) + } + "); + + Mock.Verify(x => x.GetArray(), Times.Once); + Mock.Verify(x => x.Test(true), Times.Once); } } - - [Fact] - public void Can_get_length() - { - var array = new[] {3, 4, 6}; - Mock.Setup(x => x.GetArray()).Returns(array); - Mock.Setup(x => x.Test(3)); - - RunQmlTest( - "test", - @" - var array = Net.toJsArray(test.getArray()) - test.test(array.length) - "); - - Mock.Verify(x => x.GetArray(), Times.Once); - Mock.Verify(x => x.Test(3), Times.Once); - } - [Fact] - public void Can_get_indexed() + public class ListType : BaseQmlTests { - var array = new[] {3, 4, 6}; - Mock.Setup(x => x.GetArray()).Returns(array); - Mock.Setup(x => x.Test(4)); - - RunQmlTest( - "test", - @" - var array = Net.toJsArray(test.getArray()) - test.test(array[1]) - "); - - Mock.Verify(x => x.GetArray(), Times.Once); - Mock.Verify(x => x.Test(4), Times.Once); - } - - [Fact] - public void Can_set_indexed() - { - var array = new[] {3, 4, 6}; - Mock.Setup(x => x.GetArray()).Returns(array); - - RunQmlTest( - "test", - @" - var array = Net.toJsArray(test.getArray()) - array[2] = 234 - "); - - Mock.Verify(x => x.GetArray(), Times.Once); - array[2].Should().Be(234); - } - - [Fact] - public void Can_forEach() - { - var array = new[] {3, 4, 7}; - Mock.Setup(x => x.GetArray()).Returns(array); - - RunQmlTest( - "test", - @" - var array = Net.toJsArray(test.getArray()) - array.forEach(function(value) { - test.test(value) - }) - "); - - Mock.Verify(x => x.GetArray(), Times.Once); - Mock.Verify(x => x.Test(3), Times.Once); - Mock.Verify(x => x.Test(4), Times.Once); - Mock.Verify(x => x.Test(7), Times.Once); - } + public class ListTestsQml + { + public virtual List GetList() + { + return null; + } - [Fact] - public void Can_not_push_for_array() - { - var array = new[] {3, 4, 7}; - Mock.Setup(x => x.GetArray()).Returns(array); - Mock.Setup(x => x.Test(It.IsAny())); + public virtual void Test(object value) + { + + } + } - RunQmlTest( - "test", - @" - var array = Net.toJsArray(test.getArray()) - try { - array.push(23) - } catch(err) { - test.test(true) - } - "); + [Fact] + public void Can_get_length() + { + var list = new List {4, 6, 8}; + Mock.Setup(x => x.GetList()).Returns(list); + Mock.Setup(x => x.Test(3)); + + RunQmlTest( + "test", + @" + var array = Net.toJsArray(test.getList()) + test.test(array.length) + "); + + Mock.Verify(x => x.GetList(), Times.Once); + Mock.Verify(x => x.Test(3), Times.Once); + } - Mock.Verify(x => x.GetArray(), Times.Once); - Mock.Verify(x => x.Test(true), Times.Once); - } - - [Fact] - public void Can_not_pop_for_array() - { - var array = new[] {3, 4, 7}; - Mock.Setup(x => x.GetArray()).Returns(array); - Mock.Setup(x => x.Test(It.IsAny())); + [Fact] + public void Can_get_indexed() + { + var list = new List{3, 4, 6}; + Mock.Setup(x => x.GetList()).Returns(list); + Mock.Setup(x => x.Test(4)); + + RunQmlTest( + "test", + @" + var array = Net.toJsArray(test.getList()) + test.test(array[1]) + "); + + Mock.Verify(x => x.GetList(), Times.Once); + Mock.Verify(x => x.Test(4), Times.Once); + } - RunQmlTest( - "test", - @" - var array = Net.toJsArray(test.getArray()) - try { - array.pop() - } catch(err) { - test.test(true) - } - "); - - Mock.Verify(x => x.GetArray(), Times.Once); - Mock.Verify(x => x.Test(true), Times.Once); + [Fact] + public void Can_set_indexed() + { + var list = new List{3, 4, 6}; + Mock.Setup(x => x.GetList()).Returns(list); + + RunQmlTest( + "test", + @" + var array = Net.toJsArray(test.getList()) + array[2] = 234 + "); + + Mock.Verify(x => x.GetList(), Times.Once); + list[2].Should().Be(234); + } } } } \ No newline at end of file diff --git a/src/net/Qml.Net/Internal/DefaultCallbacks.cs b/src/net/Qml.Net/Internal/DefaultCallbacks.cs index 80244e54..ae1abe83 100644 --- a/src/net/Qml.Net/Internal/DefaultCallbacks.cs +++ b/src/net/Qml.Net/Internal/DefaultCallbacks.cs @@ -4,6 +4,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Data.SqlTypes; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; @@ -48,19 +49,23 @@ namespace Qml.Net.Internal // Don't grab properties and methods for system-level types. if (Helpers.IsPrimitive(typeInfo)) return; - type.IsArray = typeInfo.IsArray; - - if (typeof(IList).IsAssignableFrom(typeInfo)) + if (typeInfo.IsArray) { - type.IsList = true; + type.IsArray = true; } - - if (typeInfo.IsGenericType) + else { - if(typeof(IList<>).IsAssignableFrom(typeInfo.GetGenericTypeDefinition())) + if (typeof(IList).IsAssignableFrom(typeInfo)) { type.IsList = true; } + else if (typeInfo.IsGenericType) + { + if(typeof(IList<>).IsAssignableFrom(typeInfo.GetGenericTypeDefinition())) + { + type.IsList = true; + } + } } foreach (var methodInfo in typeInfo.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) @@ -194,10 +199,11 @@ namespace Qml.Net.Internal } } - public void ReadProperty(IntPtr p, IntPtr t, IntPtr r) + public void ReadProperty(IntPtr p, IntPtr t, IntPtr ip, IntPtr r) { using(var property = new NetPropertyInfo(p)) using(var target = new NetReference(t)) + using(var indexParameter = ip != IntPtr.Zero ? new NetVariant(ip) : null) using(var result = new NetVariant(r)) { var o = target.Instance; @@ -208,14 +214,24 @@ namespace Qml.Net.Internal if(propertInfo == null) throw new InvalidOperationException($"Invalid property {property.Name}"); - Helpers.PackValue(propertInfo.GetValue(o), result); + if (indexParameter != null) + { + object indexParameterValue = null; + Helpers.Unpackvalue(ref indexParameterValue, indexParameter); + Helpers.PackValue(propertInfo.GetValue(o, new[]{indexParameterValue}), result); + } + else + { + Helpers.PackValue(propertInfo.GetValue(o), result); + } } } - public void WriteProperty(IntPtr p, IntPtr t, IntPtr v) + public void WriteProperty(IntPtr p, IntPtr t, IntPtr ip, IntPtr v) { using (var property = new NetPropertyInfo(p)) using (var target = new NetReference(t)) + using (var indexParameter = ip != IntPtr.Zero ? new NetVariant(ip) : null) using (var value = new NetVariant(v)) { var o = target.Instance; @@ -229,7 +245,16 @@ namespace Qml.Net.Internal object newValue = null; Helpers.Unpackvalue(ref newValue, value); - propertInfo.SetValue(o, newValue); + if (indexParameter != null) + { + object indexParameterValue = null; + Helpers.Unpackvalue(ref indexParameterValue, indexParameter); + propertInfo.SetValue(o, newValue, new[]{indexParameterValue}); + } + else + { + propertInfo.SetValue(o, newValue); + } } } diff --git a/src/net/Qml.Net/Internal/Types/Callbacks.cs b/src/net/Qml.Net/Internal/Types/Callbacks.cs index 063b96ec..b227cc60 100644 --- a/src/net/Qml.Net/Internal/Types/Callbacks.cs +++ b/src/net/Qml.Net/Internal/Types/Callbacks.cs @@ -40,12 +40,6 @@ namespace Qml.Net.Internal.Types [NativeSymbol(Entrypoint = "type_info_callbacks_instantiateType")] IntPtr InstantiateType(IntPtr type); - [NativeSymbol(Entrypoint = "type_info_callbacks_readProperty")] - void ReadProperty(IntPtr property, IntPtr target, IntPtr result); - - [NativeSymbol(Entrypoint = "type_info_callbacks_writeProperty")] - void WriteProperty(IntPtr property, IntPtr target, IntPtr value); - [NativeSymbol(Entrypoint = "type_info_callbacks_invokeMethod")] void InvokeMethod(IntPtr method, IntPtr target, IntPtr variants, IntPtr result); } @@ -64,9 +58,9 @@ namespace Qml.Net.Internal.Types IntPtr InstantiateType(IntPtr type); - void ReadProperty(IntPtr property, IntPtr target, IntPtr result); + void ReadProperty(IntPtr property, IntPtr target, IntPtr indexProperty, IntPtr result); - void WriteProperty(IntPtr property, IntPtr target, IntPtr value); + void WriteProperty(IntPtr property, IntPtr target, IntPtr indexProperty, IntPtr value); void InvokeMethod(IntPtr method, IntPtr target, IntPtr parameters, IntPtr result); @@ -110,15 +104,15 @@ namespace Qml.Net.Internal.Types [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void ReleaseNetDelegateGCHandleDelegate(IntPtr handle); - + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate IntPtr InstantiateTypeDelgate(IntPtr type); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate void ReadPropertyDelegate(IntPtr property, IntPtr target, IntPtr result); + delegate void ReadPropertyDelegate(IntPtr property, IntPtr target, IntPtr indexParameter, IntPtr result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate void WritePropertyDelegate(IntPtr property, IntPtr target, IntPtr value); + delegate void WritePropertyDelegate(IntPtr property, IntPtr target, IntPtr indexParameter, IntPtr value); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void InvokeMethodDelegate(IntPtr method, IntPtr target, IntPtr variants, IntPtr result); @@ -209,14 +203,14 @@ namespace Qml.Net.Internal.Types return _callbacks.InstantiateType(type); } - private void ReadProperty(IntPtr property, IntPtr target, IntPtr result) + private void ReadProperty(IntPtr property, IntPtr target, IntPtr indexParameter, IntPtr result) { - _callbacks.ReadProperty(property, target, result); + _callbacks.ReadProperty(property, target, indexParameter, result); } - private void WriteProperty(IntPtr property, IntPtr target, IntPtr value) + private void WriteProperty(IntPtr property, IntPtr target, IntPtr indexParameter, IntPtr value) { - _callbacks.WriteProperty(property, target, value); + _callbacks.WriteProperty(property, target, indexParameter, value); } private void InvokeMethod(IntPtr method, IntPtr target, IntPtr variants, IntPtr result)