mirror of
https://github.com/qmlnet/qmlnet.git
synced 2026-05-21 06:45:32 -06:00
Wrapping .NET list as js array.
This commit is contained in:
parent
275bff1c84
commit
f62f3c0adf
12 changed files with 353 additions and 187 deletions
|
|
@ -260,8 +260,8 @@ ReturnedValue NetObject::method_toJsArray(const FunctionObject *b, const Value *
|
|||
}
|
||||
|
||||
QSharedPointer<NetReference> 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));
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ int NetValueMetaObject::metaCall(QMetaObject::Call c, int idx, void **a)
|
|||
QSharedPointer<NetTypeInfo> propertyType = propertyInfo->getReturnType();
|
||||
|
||||
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(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<NetVariant> newValue = QSharedPointer<NetVariant>(new NetVariant());
|
||||
NetMetaValueUnpack(propertyType->getPrefVariantType(), newValue, a[0]);
|
||||
|
||||
writeProperty(propertyInfo, instance, newValue);
|
||||
writeProperty(propertyInfo, instance, nullptr, newValue);
|
||||
}
|
||||
break;
|
||||
case InvokeMetaMethod:
|
||||
|
|
|
|||
|
|
@ -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<NetReference> instantiateType(QSharedPointer<NetTypeInfo> type) {
|
|||
return result;
|
||||
}
|
||||
|
||||
void readProperty(QSharedPointer<NetPropertyInfo> property, QSharedPointer<NetReference> target, QSharedPointer<NetVariant> result) {
|
||||
void readProperty(QSharedPointer<NetPropertyInfo> property, QSharedPointer<NetReference> target, QSharedPointer<NetVariant> indexParameter, QSharedPointer<NetVariant> 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<NetPropertyInfo> property, QSharedPointer<NetReference> target, QSharedPointer<NetVariant> value) {
|
||||
void writeProperty(QSharedPointer<NetPropertyInfo> property, QSharedPointer<NetReference> target, QSharedPointer<NetVariant> indexParameter, QSharedPointer<NetVariant> 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.
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ void loadTypeInfo(QSharedPointer<NetTypeInfo> typeInfo);
|
|||
|
||||
QSharedPointer<NetReference> instantiateType(QSharedPointer<NetTypeInfo> type);
|
||||
|
||||
void readProperty(QSharedPointer<NetPropertyInfo> property, QSharedPointer<NetReference> target, QSharedPointer<NetVariant> result);
|
||||
void readProperty(QSharedPointer<NetPropertyInfo> property, QSharedPointer<NetReference> target, QSharedPointer<NetVariant> indexParameter, QSharedPointer<NetVariant> result);
|
||||
|
||||
void writeProperty(QSharedPointer<NetPropertyInfo> property, QSharedPointer<NetReference> target, QSharedPointer<NetVariant> value);
|
||||
void writeProperty(QSharedPointer<NetPropertyInfo> property, QSharedPointer<NetReference> target, QSharedPointer<NetVariant> indexParameter, QSharedPointer<NetVariant> value);
|
||||
|
||||
void invokeNetMethod(QSharedPointer<NetMethodInfo> method, QSharedPointer<NetReference> target, QSharedPointer<NetVariantList> parameters, QSharedPointer<NetVariant> result);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include <QmlNet/types/NetTypeArrayFacade.h>
|
||||
#include <QmlNet/types/NetTypeArrayFacadeArray.h>
|
||||
#include <QmlNet/types/NetTypeArrayFacadeList.h>
|
||||
#include <QmlNet/types/NetTypeInfo.h>
|
||||
|
||||
NetTypeArrayFacade::NetTypeArrayFacade()
|
||||
|
|
@ -17,6 +18,14 @@ QSharedPointer<NetTypeArrayFacade> NetTypeArrayFacade::fromType(QSharedPointer<N
|
|||
return facade.dynamicCast<NetTypeArrayFacade>();
|
||||
}
|
||||
|
||||
if(type->isList()) {
|
||||
QSharedPointer<NetTypeArrayFacade_List> facade = QSharedPointer<NetTypeArrayFacade_List>(new NetTypeArrayFacade_List(type));
|
||||
if(facade->isIncomplete()) {
|
||||
return nullptr;
|
||||
}
|
||||
return facade.dynamicCast<NetTypeArrayFacade>();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ bool NetTypeArrayFacade_Array::isFixed()
|
|||
uint NetTypeArrayFacade_Array::getLength(QSharedPointer<NetReference> reference)
|
||||
{
|
||||
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
|
||||
readProperty(_lengthProperty, reference, result);
|
||||
readProperty(_lengthProperty, reference, nullptr, result);
|
||||
return static_cast<uint>(result->getInt());
|
||||
}
|
||||
|
||||
|
|
|
|||
59
src/native/QmlNet/QmlNet/types/NetTypeArrayFacadeList.cpp
Normal file
59
src/native/QmlNet/QmlNet/types/NetTypeArrayFacadeList.cpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
#include <QmlNet/types/NetTypeArrayFacadeList.h>
|
||||
#include <QmlNet/types/NetTypeInfo.h>
|
||||
#include <QmlNet/types/NetMethodInfo.h>
|
||||
#include <QmlNet/types/NetPropertyInfo.h>
|
||||
#include <QmlNet/qml/NetVariant.h>
|
||||
#include <QmlNet/qml/NetVariantList.h>
|
||||
#include <QmlNet/types/Callbacks.h>
|
||||
|
||||
NetTypeArrayFacade_List::NetTypeArrayFacade_List(QSharedPointer<NetTypeInfo> type) :
|
||||
_isIncomplete(false)
|
||||
{
|
||||
for(int x = 0; x < type->getPropertyCount(); x++) {
|
||||
QSharedPointer<NetPropertyInfo> 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<NetReference> reference)
|
||||
{
|
||||
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
|
||||
readProperty(_lengthProperty, reference, nullptr, result);
|
||||
return static_cast<uint>(result->getInt());
|
||||
}
|
||||
|
||||
QSharedPointer<NetVariant> NetTypeArrayFacade_List::getIndexed(QSharedPointer<NetReference> reference, int index)
|
||||
{
|
||||
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
|
||||
QSharedPointer<NetVariant> indexParameter = QSharedPointer<NetVariant>(new NetVariant());
|
||||
indexParameter->setInt(index);
|
||||
readProperty(_itemProperty, reference, indexParameter, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void NetTypeArrayFacade_List::setIndexed(QSharedPointer<NetReference> reference, int index, QSharedPointer<NetVariant> value)
|
||||
{
|
||||
QSharedPointer<NetVariant> indexParameter = QSharedPointer<NetVariant>(new NetVariant());
|
||||
indexParameter->setInt(index);
|
||||
writeProperty(_itemProperty, reference, indexParameter, value);
|
||||
}
|
||||
24
src/native/QmlNet/QmlNet/types/NetTypeArrayFacadeList.h
Normal file
24
src/native/QmlNet/QmlNet/types/NetTypeArrayFacadeList.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef NETTYPEARRAYFACADELIST_H
|
||||
#define NETTYPEARRAYFACADELIST_H
|
||||
|
||||
#include <QmlNet/types/NetTypeArrayFacade.h>
|
||||
|
||||
class NetMethodInfo;
|
||||
class NetPropertyInfo;
|
||||
|
||||
class NetTypeArrayFacade_List : public NetTypeArrayFacade
|
||||
{
|
||||
public:
|
||||
NetTypeArrayFacade_List(QSharedPointer<NetTypeInfo> type);
|
||||
bool isIncomplete();
|
||||
bool isFixed();
|
||||
uint getLength(QSharedPointer<NetReference> reference);
|
||||
QSharedPointer<NetVariant> getIndexed(QSharedPointer<NetReference> reference, int index);
|
||||
void setIndexed(QSharedPointer<NetReference> reference, int index, QSharedPointer<NetVariant> value);
|
||||
private:
|
||||
bool _isIncomplete;
|
||||
QSharedPointer<NetPropertyInfo> _lengthProperty;
|
||||
QSharedPointer<NetPropertyInfo> _itemProperty;
|
||||
};
|
||||
|
||||
#endif // NETTYPEARRAYFACADELIST_H
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<ArrayTests.ArrayTestsQml>
|
||||
public class ArrayTests
|
||||
{
|
||||
public class ArrayTestsQml
|
||||
public class ArrayType : BaseQmlTests<ArrayType.ArrayTestsQml>
|
||||
{
|
||||
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<object>()));
|
||||
|
||||
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<object>()));
|
||||
|
||||
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<ListType.ListTestsQml>
|
||||
{
|
||||
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<int> 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<object>()));
|
||||
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<int> {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<object>()));
|
||||
[Fact]
|
||||
public void Can_get_indexed()
|
||||
{
|
||||
var list = new List<int>{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<int>{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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue