Simplified the global "Net" object. Remove toJsArray until I can dedicate more time to flush it out.

This commit is contained in:
Paul Knopf 2018-09-23 17:25:19 -04:00
parent 59d475fb73
commit 7227c30b34
20 changed files with 144 additions and 1079 deletions

View file

@ -1,45 +0,0 @@
#ifndef JSNETARRAY_H
#define JSNETARRAY_H
#include <QmlNet/qml/NetValue.h>
#include <private/qv4functionobject_p.h>
namespace QV4 {
namespace Heap {
struct NetArray : Object {
void init();
void destroy();
QV4::Value* object;
};
}
struct NetArray : Object
{
V4_OBJECT2(NetArray, Object)
V4_NEEDS_DESTROY
Q_MANAGED_TYPE(ArrayObject)
static ReturnedValue create(ExecutionEngine *engine, NetValue* netValue);
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
static void method_length(const BuiltinFunction *, Scope &, CallData *callData);
static void method_push(const BuiltinFunction *, Scope &, CallData *callData);
static void method_pop(const BuiltinFunction *, Scope &, CallData *callData);
static void method_forEach(const BuiltinFunction *, Scope &, CallData *callData);
#else
static ReturnedValue method_length(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_push(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_pop(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_forEach(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
#endif
static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
static bool putIndexed(Managed *m, uint index, const Value &value);
};
}
#endif // JSNETARRAY_H

View file

@ -1,182 +0,0 @@
#include <QmlNet/qml/JsNetArray.h>
#include <QmlNet/types/NetMethodInfo.h>
#include <QmlNet/types/Callbacks.h>
#include <QmlNet/types/NetTypeArrayFacade.h>
#include <QVariant>
#include <private/qv4qobjectwrapper_p.h>
QT_BEGIN_NAMESPACE
using namespace QV4;
DEFINE_OBJECT_VTABLE(NetArray);
void Heap::NetArray::init()
{
Object::init();
QV4::Scope scope(internalClass->engine);
QV4::ScopedObject o(scope, this);
o->setArrayType(Heap::ArrayData::Custom);
o->defineAccessorProperty(QStringLiteral("length"), QV4::NetArray::method_length, nullptr);
o->defineDefaultProperty(QStringLiteral("push"), QV4::NetArray::method_push);
o->defineDefaultProperty(QStringLiteral("pop"), QV4::NetArray::method_pop);
o->defineDefaultProperty(QStringLiteral("forEach"), QV4::NetArray::method_forEach);
object = scope.engine->memoryManager->m_persistentValues->allocate();
}
void Heap::NetArray::destroy()
{
QV4::PersistentValueStorage::free(object);
Object::destroy();
}
ReturnedValue NetArray::create(ExecutionEngine *engine, NetValue* netValue)
{
Scope scope(engine);
Scoped<NetArray> r(scope, engine->memoryManager->allocObject<NetArray>());
*r->d()->object = QObjectWrapper::wrap(scope.engine, netValue);
return r.asReturnedValue();
}
void NetArray::method_length(const BuiltinFunction *, Scope &scope, CallData *callData)
{
ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
NetArray* netArray = instance->as<NetArray>();
Scoped<QV4::QObjectWrapper> wrapper(scope, netArray->d()->object);
NetValue* netValue = reinterpret_cast<NetValue*>(wrapper->d()->object());
QSharedPointer<NetTypeArrayFacade> arrayFacade = netValue->getNetReference()->getTypeInfo()->getArrayFacade();
if(arrayFacade == nullptr) {
THROW_GENERIC_ERROR("The wrapped object can't be treated as an array.");
}
scope.result = Encode(arrayFacade->getLength(netValue->getNetReference()));
}
void NetArray::method_push(const BuiltinFunction *, Scope &scope, CallData *callData)
{
ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
NetArray* netArray = instance->as<NetArray>();
Scoped<QV4::QObjectWrapper> wrapper(scope, netArray->d()->object);
NetValue* netValue = reinterpret_cast<NetValue*>(wrapper->d()->object());
QSharedPointer<NetTypeArrayFacade> arrayFacade = netValue->getNetReference()->getTypeInfo()->getArrayFacade();
if(arrayFacade == nullptr) {
THROW_GENERIC_ERROR("The wrapped object can't be treated as an array.");
}
if(arrayFacade->isFixed()) {
THROW_GENERIC_ERROR("Can't modify a fixed .NET list type.");
}
uint len = instance->getLength();
if(len == 0) {
RETURN_UNDEFINED();
}
for (int i = 0, ei = callData->argc; i < ei; ++i) {
QV4::ScopedValue valueScope(scope, callData->args[i]);
QJSValue valueJsValue(scope.engine, valueScope->asReturnedValue());
arrayFacade->push(netValue->getNetReference(), NetVariant::fromQJSValue(valueJsValue));
}
scope.result = Encode(instance->getLength());
}
void NetArray::method_pop(const BuiltinFunction *, Scope &scope, CallData *callData)
{
ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
NetArray* netArray = instance->as<NetArray>();
Scoped<QV4::QObjectWrapper> wrapper(scope, netArray->d()->object);
NetValue* netValue = reinterpret_cast<NetValue*>(wrapper->d()->object());
QSharedPointer<NetTypeArrayFacade> arrayFacade = netValue->getNetReference()->getTypeInfo()->getArrayFacade();
if(arrayFacade == nullptr) {
THROW_GENERIC_ERROR("The wrapped object can't be treated as an array.");
}
if(arrayFacade->isFixed()) {
THROW_GENERIC_ERROR("Can't modify a fixed .NET list type.");
}
uint len = instance->getLength();
if(len == 0) {
RETURN_UNDEFINED();
}
QSharedPointer<NetVariant> result = arrayFacade->pop(netValue->getNetReference());
if(result == nullptr) {
scope.result = Encode::null();
}
QJSValue resultJsValue = result->toQJSValue(scope.engine->jsEngine());
scope.result = scope.engine->fromVariant(resultJsValue.toVariant());
}
void NetArray::method_forEach(const BuiltinFunction *, Scope &scope, CallData *callData)
{
ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
uint len = instance->getLength();
ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
THROW_TYPE_ERROR();
ScopedCallData cData(scope, 3);
cData->thisObject = callData->argument(1);
cData->args[2] = instance;
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
bool exists;
v = instance->getIndexed(k, &exists);
if (!exists)
continue;
cData->args[0] = v;
cData->args[1] = Primitive::fromDouble(k);
callback->call(scope, cData);
}
RETURN_UNDEFINED();
}
ReturnedValue NetArray::getIndexed(const Managed *m, uint index, bool *hasProperty)
{
const NetArray *netArray = static_cast<const NetArray*>(m);
Scope scope(netArray->engine());
QV4::Scoped<QV4::QObjectWrapper> wrapper(scope, netArray->d()->object);
NetValue* netValue = reinterpret_cast<NetValue*>(wrapper->d()->object());
QSharedPointer<NetTypeArrayFacade> arrayFacade = netValue->getNetReference()->getTypeInfo()->getArrayFacade();
if(hasProperty)
*hasProperty = true;
if(arrayFacade == nullptr) {
return scope.engine->throwError(QString::fromUtf8("The wrapped object can't be treated as an array."));
}
QSharedPointer<NetVariant> result = arrayFacade->getIndexed(netValue->getNetReference(), index);
QJSValue resultJsValue = result->toQJSValue(scope.engine->jsEngine());
return scope.engine->fromVariant(resultJsValue.toVariant());
}
bool NetArray::putIndexed(Managed *m, uint index, const Value &value)
{
const NetArray *netArray = static_cast<const NetArray*>(m);
Scope scope(netArray->engine());
QV4::Scoped<QV4::QObjectWrapper> wrapper(scope, netArray->d()->object);
NetValue* netValue = reinterpret_cast<NetValue*>(wrapper->d()->object());
QSharedPointer<NetTypeArrayFacade> arrayFacade = netValue->getNetReference()->getTypeInfo()->getArrayFacade();
if(arrayFacade == nullptr) {
return scope.engine->throwError(QString::fromUtf8("The wrapped object can't be treated as an array."));
}
QV4::ScopedValue valueScope(scope, value);
QJSValue valueJsValue(scope.engine, valueScope->asReturnedValue());
arrayFacade->setIndexed(netValue->getNetReference(), index, NetVariant::fromQJSValue(valueJsValue));
return true;
}

View file

@ -1,203 +0,0 @@
#include <QmlNet/qml/JsNetArray.h>
#include <QmlNet/types/NetMethodInfo.h>
#include <QmlNet/types/Callbacks.h>
#include <QmlNet/types/NetTypeArrayFacade.h>
#include <QVariant>
#include <private/qv4qobjectwrapper_p.h>
QT_BEGIN_NAMESPACE
using namespace QV4;
DEFINE_OBJECT_VTABLE(NetArray);
void Heap::NetArray::init()
{
Object::init();
QV4::Scope scope(internalClass->engine);
QV4::ScopedObject o(scope, this);
o->setArrayType(Heap::ArrayData::Custom);
o->defineAccessorProperty(QStringLiteral("length"), QV4::NetArray::method_length, nullptr);
o->defineDefaultProperty(QStringLiteral("push"), QV4::NetArray::method_push);
o->defineDefaultProperty(QStringLiteral("pop"), QV4::NetArray::method_pop);
o->defineDefaultProperty(QStringLiteral("forEach"), QV4::NetArray::method_forEach);
object = scope.engine->memoryManager->m_persistentValues->allocate();
}
void Heap::NetArray::destroy()
{
QV4::PersistentValueStorage::free(object);
Object::destroy();
}
ReturnedValue NetArray::create(ExecutionEngine *engine, NetValue* netValue)
{
Scope scope(engine);
Scoped<NetArray> r(scope, engine->memoryManager->allocObject<NetArray>());
*r->d()->object = QObjectWrapper::wrap(scope.engine, netValue);
return r.asReturnedValue();
}
ReturnedValue NetArray::method_length(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
Scoped<QV4::NetArray> netArray(scope, thisObject->as<QV4::NetArray>());
Scoped<QV4::QObjectWrapper> wrapper(scope, netArray->d()->object);
if (!wrapper) {
THROW_GENERIC_ERROR("No reference to the wrapped QObject exists.");
}
NetValue* netValue = reinterpret_cast<NetValue*>(wrapper->d()->object());
QSharedPointer<NetTypeArrayFacade> arrayFacade = netValue->getNetReference()->getTypeInfo()->getArrayFacade();
if(arrayFacade == nullptr) {
THROW_GENERIC_ERROR("The wrapped object can't be treated as an array.");
}
return Encode(arrayFacade->getLength(netValue->getNetReference()));
}
ReturnedValue NetArray::method_push(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
ScopedObject instance(scope, thisObject->toObject(scope.engine));
Scoped<QV4::NetArray> netArray(scope, thisObject->as<QV4::NetArray>());
Scoped<QV4::QObjectWrapper> wrapper(scope, netArray->d()->object);
if (!wrapper) {
THROW_GENERIC_ERROR("No reference to the wrapped QObject exists.");
}
NetValue* netValue = reinterpret_cast<NetValue*>(wrapper->d()->object());
QSharedPointer<NetTypeArrayFacade> arrayFacade = netValue->getNetReference()->getTypeInfo()->getArrayFacade();
if(arrayFacade == nullptr) {
THROW_GENERIC_ERROR("The wrapped object can't be treated as an array.");
}
if(arrayFacade->isFixed()) {
THROW_GENERIC_ERROR("Can't modify a fixed .NET list type.");
}
for (int i = 0, ei = argc; i < ei; ++i) {
QV4::ScopedValue valueScope(scope, argv[i]);
QJSValue valueJsValue(scope.engine, valueScope->asReturnedValue());
arrayFacade->push(netValue->getNetReference(), NetVariant::fromQJSValue(valueJsValue));
}
return Encode(instance->getLength());
}
ReturnedValue NetArray::method_pop(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
ScopedObject instance(scope, thisObject->toObject(scope.engine));
Scoped<QV4::NetArray> netArray(scope, thisObject->as<QV4::NetArray>());
Scoped<QV4::QObjectWrapper> wrapper(scope, netArray->d()->object);
if (!wrapper) {
THROW_GENERIC_ERROR("No reference to the wrapped QObject exists.");
}
NetValue* netValue = reinterpret_cast<NetValue*>(wrapper->d()->object());
QSharedPointer<NetTypeArrayFacade> arrayFacade = netValue->getNetReference()->getTypeInfo()->getArrayFacade();
if(arrayFacade == nullptr) {
THROW_GENERIC_ERROR("The wrapped object can't be treated as an array.");
}
if(arrayFacade->isFixed()) {
THROW_GENERIC_ERROR("Can't modify a fixed .NET list type.");
}
uint len = instance->getLength();
if(len == 0) {
RETURN_UNDEFINED();
}
QSharedPointer<NetVariant> result = arrayFacade->pop(netValue->getNetReference());
if(result == nullptr) {
return Encode::null();
}
QJSValue resultJsValue = result->toQJSValue(scope.engine->jsEngine());
return scope.engine->fromVariant(resultJsValue.toVariant());
}
ReturnedValue NetArray::method_forEach(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
uint len = instance->getLength();
if (!argc || !argv->isFunctionObject())
THROW_TYPE_ERROR();
const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
Value *arguments = scope.alloc(3);
for (uint k = 0; k < len; ++k) {
bool exists;
arguments[0] = instance->getIndexed(k, &exists);
if (!exists)
continue;
arguments[1] = Primitive::fromDouble(k);
arguments[2] = instance;
callback->call(that, arguments, 3);
}
RETURN_UNDEFINED();
}
ReturnedValue NetArray::getIndexed(const Managed *m, uint index, bool *hasProperty)
{
const NetArray *netArray = static_cast<const NetArray*>(m);
Scope scope(netArray->engine());
if(hasProperty)
*hasProperty = true;
QV4::Scoped<QV4::QObjectWrapper> wrapper(scope, netArray->d()->object);
if (!wrapper) {
THROW_GENERIC_ERROR("No reference to the wrapped QObject exists.");
}
NetValue* netValue = reinterpret_cast<NetValue*>(wrapper->d()->object());
QSharedPointer<NetTypeArrayFacade> arrayFacade = netValue->getNetReference()->getTypeInfo()->getArrayFacade();
if(arrayFacade == nullptr) {
THROW_GENERIC_ERROR("The wrapped object can't be treated as an array.");
}
QSharedPointer<NetVariant> result = arrayFacade->getIndexed(netValue->getNetReference(), static_cast<int>(index));
QJSValue resultJsValue = result->toQJSValue(scope.engine->jsEngine());
return scope.engine->fromVariant(resultJsValue.toVariant());
}
bool NetArray::putIndexed(Managed *m, uint index, const Value &value)
{
const NetArray *netArray = static_cast<const NetArray*>(m);
Scope scope(netArray->engine());
QV4::ScopedValue valueScope(scope, value);
QJSValue valueJsValue(scope.engine, valueScope->asReturnedValue());
QV4::Scoped<QV4::QObjectWrapper> wrapper(scope, netArray->d()->object);
if (!wrapper) {
THROW_GENERIC_ERROR("No reference to the wrapped QObject exists.");
}
NetValue* netValue = reinterpret_cast<NetValue*>(wrapper->d()->object());
QSharedPointer<NetTypeArrayFacade> arrayFacade = netValue->getNetReference()->getTypeInfo()->getArrayFacade();
if(arrayFacade == nullptr) {
THROW_GENERIC_ERROR("The wrapped object can't be treated as an array.");
}
arrayFacade->setIndexed(netValue->getNetReference(),
index,
NetVariant::fromQJSValue(valueJsValue));
return true;
}

View file

@ -1,345 +1,121 @@
#include <QmlNet/qml/JsNetObject.h>
#include <QmlNet/qml/NetVariant.h>
#include <QmlNet/types/Callbacks.h>
#include <QmlNet/qml/NetValue.h>
#include <QmlNet/qml/JsNetArray.h>
#include <QmlNet/types/NetTypeManager.h>
#include <private/qv4qobjectwrapper_p.h>
#include <QmlNet/qml/NetListModel.h>
#include <QQmlEngine>
#include <QDebug>
using namespace QV4;
DEFINE_OBJECT_VTABLE(NetObject);
void Heap::NetObject::init() {
Scope scope(internalClass->engine);
ScopedObject o(scope, this);
o->defineDefaultProperty(QStringLiteral("gcCollect"), QV4::NetObject::method_gccollect);
o->defineDefaultProperty(QStringLiteral("await"), QV4::NetObject::method_await);
o->defineDefaultProperty(QStringLiteral("cancelTokenSource"), QV4::NetObject::method_cancelTokenSource);
o->defineDefaultProperty(QStringLiteral("serialize"), QV4::NetObject::method_serialize);
o->defineDefaultProperty(QStringLiteral("toJsArray"), QV4::NetObject::method_toJsArray);
o->defineDefaultProperty(QStringLiteral("toListModel"), QV4::NetObject::method_toListModel);
}
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
void NetObject::method_gccollect(const BuiltinFunction *, Scope &scope, CallData *callData) {
int maxGeneration = 0;
if(callData->argc > 0) {
maxGeneration = callData->args[0].toNumber();
}
gcCollect(maxGeneration);
scope.result = QV4::Encode::undefined();
}
void NetObject::method_await(const BuiltinFunction *, Scope &scope, CallData *callData) {
scope.result = QV4::Encode::undefined();
if (callData->argc != 2 && callData->argc != 3) {
qWarning() << "Invalid number of parameters passed to Net.await(task, callback)";
return;
}
ScopedValue task(scope, callData->args[0]);
ScopedValue successCallback(scope, callData->args[1]);
ScopedValue failureCallback(scope);
if(callData->argc == 3) {
failureCallback = ScopedValue(scope, callData->args[2]);
}
if(task->isNullOrUndefined()) {
qWarning() << "No task for Net.await(task, callback)";
return;
}
if(successCallback->isNullOrUndefined()) {
qWarning() << "No callback for Net.await(task, callback)";
return;
}
QJSValue taskJsValue(scope.engine, task->asReturnedValue());
QJSValue callbackJsValue(scope.engine, successCallback->asReturnedValue());
QJSValue failureJsValue(scope.engine, failureCallback->asReturnedValue());
QObject* qObject = taskJsValue.toQObject();
NetValueInterface* netValue = qobject_cast<NetValueInterface*>(qObject);
if(!netValue) {
qWarning() << "Invalid task object passed to Net.await(task, callback)";
return;
}
// Send the method to .NET, await the task, and call the callback.
awaitTask(netValue->getNetReference(),
QSharedPointer<NetJSValue>(new NetJSValue(callbackJsValue)),
failureJsValue.isNull()
? QSharedPointer<NetJSValue>(nullptr)
: QSharedPointer<NetJSValue>(new NetJSValue(failureJsValue)));
}
void NetObject::method_cancelTokenSource(const BuiltinFunction *, Scope &scope, CallData *callData) {
Q_UNUSED(callData);
QSharedPointer<NetTypeInfo> typeInfo = NetTypeManager::getTypeInfo("System.Threading.CancellationTokenSource");
if(typeInfo == nullptr) {
qWarning() << "Couldn't get cancellation token type for platform, please file a bug";
scope.result = QV4::Encode::undefined();
return;
}
QSharedPointer<NetReference> netReference = instantiateType(typeInfo);
if(netReference == nullptr) {
qWarning() << "Couldn't create cancellation token for platform, please file a bug";
scope.result = QV4::Encode::undefined();
return;
}
NetValue* netValue = NetValue::forInstance(netReference);
scope.result = QV4::QObjectWrapper::wrap(scope.engine, netValue);
}
void NetObject::method_serialize(const BuiltinFunction *, Scope &scope, CallData *callData)
JsNetObject::JsNetObject()
{
if(callData->argc != 1) {
THROW_GENERIC_ERROR("Net.serialize(): Missing instance parameter");
}
QString JsNetObject::serialize(QJSValue value)
{
if(value.isNull() || value.isUndefined()) {
qWarning("Net.serialize(): Instance parameter must not be null or undefined");
return QString();
}
ScopedValue instance(scope, callData->args[0]);
if(instance->isNullOrUndefined()) {
THROW_GENERIC_ERROR("Net.serialize(): Instance parameter must not be null or undefined");
}
QJSValue instanceJsValue(scope.engine, instance->asReturnedValue());
QSharedPointer<NetVariant> value = NetVariant::fromQJSValue(instanceJsValue);
if(value->getVariantType() != NetVariantTypeEnum_Object) {
THROW_GENERIC_ERROR("Net.serialize(): Parameter is not a .NET object");
QSharedPointer<NetVariant> netVaraint = NetVariant::fromQJSValue(value);
if(netVaraint->getVariantType() != NetVariantTypeEnum_Object) {
qWarning("Net.serialize(): Parameter is not a .NET object");
return QString();
}
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
bool serializationResult = serializeNetToString(value->getNetReference(), result);
bool serializationResult = QmlNet::serializeNetToString(netVaraint->getNetReference(), result);
if(!serializationResult) {
THROW_GENERIC_ERROR("Net.serialize(): Could not serialize object.");
qWarning("Net.serialize(): Could not serialize object.");
return QString();
}
scope.result = scope.engine->newString(result->getString());
return result->getString();
}
void NetObject::method_toJsArray(const BuiltinFunction *, Scope &scope, CallData *callData)
QVariant JsNetObject::cancelTokenSource()
{
if(callData->argc != 1) {
THROW_GENERIC_ERROR("Net.toJsArray(): Missing instance parameter");
}
QV4::ScopedValue instance(scope, callData->args[0]);
if(instance->isNullOrUndefined()) {
THROW_GENERIC_ERROR("Net.toJsArray(): Instance parameter must not be null or undefined");
}
QJSValue instanceJsValue(scope.engine, instance->asReturnedValue());
QSharedPointer<NetVariant> value = NetVariant::fromQJSValue(instanceJsValue);
if(value->getVariantType() != NetVariantTypeEnum_Object) {
THROW_GENERIC_ERROR("Net.toJsArray(): Parameter is not a .NET object");
}
QSharedPointer<NetReference> netReference = value->getNetReference();
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.");
}
scope.result = NetArray::create(scope.engine, NetValue::forInstance(netReference));
}
void NetObject::method_toListModel(const BuiltinFunction *, Scope &scope, CallData *callData)
{
if(callData->argc != 1) {
THROW_GENERIC_ERROR("Net.toListModel(): Missing instance parameter");
}
qInfo("TOJSARRAYY");
QV4::ScopedValue instance(scope, callData->args[0]);
if(instance->isNullOrUndefined()) {
THROW_GENERIC_ERROR("Net.toListModel(): Instance parameter must not be null or undefined");
}
QJSValue instanceJsValue(scope.engine, instance->asReturnedValue());
QSharedPointer<NetVariant> value = NetVariant::fromQJSValue(instanceJsValue);
if(value->getVariantType() != NetVariantTypeEnum_Object) {
THROW_GENERIC_ERROR("Net.toListModel(): Parameter is not a .NET object");
}
QSharedPointer<NetReference> netReference = value->getNetReference();
NetListModel* listModel = NetListModel::fromReference(netReference);
if(listModel == nullptr) {
THROW_GENERIC_ERROR("Net.toListModel(): Parameter is not a type that can be wrapped by a list model.");
}
QQmlEngine::setObjectOwnership(listModel, QQmlEngine::JavaScriptOwnership);
scope.result = QObjectWrapper::wrap(scope.engine, listModel);
}
#else
ReturnedValue NetObject::method_gccollect(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) {
Q_UNUSED(b);
Q_UNUSED(thisObject);
int maxGeneration = 0;
if(argc > 0) {
maxGeneration = static_cast<int>(argv[0].toNumber());
}
gcCollect(maxGeneration);
return Encode::undefined();
}
ReturnedValue NetObject::method_await(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) {
QV4::Scope scope(b);
if(argc != 2 && argc != 3) {
qWarning() << "Invalid number of parameters passed to Net.await(task, callback)";
return Encode::undefined();
}
QV4::ScopedValue task(scope, argv[0]);
QV4::ScopedValue successCallback(scope, argv[1]);
QV4::ScopedValue failureCallback(scope, Encode::null());
if(argc == 3) {
// We are passing in a failure callback
failureCallback = argv[2];
}
if(task->isNullOrUndefined()) {
qWarning() << "No task for Net.await(task, callback)";
return Encode::undefined();
}
if(successCallback->isNullOrUndefined()) {
qWarning() << "No callback for Net.await(task, callback)";
return Encode::undefined();
}
QJSValue taskJsValue(scope.engine, task->asReturnedValue());
QJSValue successCallbackJsValue(scope.engine, successCallback->asReturnedValue());
QJSValue failureCallbackJsValue(scope.engine, failureCallback->asReturnedValue());
if(!taskJsValue.isQObject()) {
qWarning() << "Invalid task object passed to Net.await(task, callback)";
return Encode::undefined();
}
if(!successCallbackJsValue.isCallable()) {
qWarning() << "Invalid function passed for success callback";
return Encode::undefined();
}
if(!failureCallbackJsValue.isNull() && !failureCallbackJsValue.isCallable()) {
qWarning() << "Invalid function passed for failure callback";
return Encode::undefined();
}
QObject* qObject = taskJsValue.toQObject();
NetValueInterface* netValue = qobject_cast<NetValueInterface*>(qObject);
if(!netValue) {
qWarning() << "Invalid task object passed to Net.await(task, callback)";
return Encode::undefined();
}
// Send the method to .NET, await the task, and call the callback.
awaitTask(netValue->getNetReference(),
QSharedPointer<NetJSValue>(new NetJSValue(successCallbackJsValue)),
failureCallbackJsValue.isNull()
? QSharedPointer<NetJSValue>(nullptr)
: QSharedPointer<NetJSValue>(new NetJSValue(failureCallbackJsValue)));
return Encode::undefined();
}
ReturnedValue NetObject::method_cancelTokenSource(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) {
QV4::Scope scope(b);
QSharedPointer<NetTypeInfo> typeInfo = NetTypeManager::getTypeInfo("System.Threading.CancellationTokenSource");
if(typeInfo == nullptr) {
qWarning() << "Couldn't get cancellation token type for platform, please file a bug";
return Encode::undefined();
qWarning("Couldn't get cancellation token type for platform, please file a bug");
return QVariant();
}
QSharedPointer<NetReference> netReference = instantiateType(typeInfo);
QSharedPointer<NetReference> netReference = QmlNet::instantiateType(typeInfo);
if(netReference == nullptr) {
qWarning() << "Couldn't create cancellation token for platform, please file a bug";
return Encode::undefined();
qWarning("Couldn't create cancellation token for platform, please file a bug");
return QVariant();
}
NetValue* netValue = NetValue::forInstance(netReference);
return QV4::QObjectWrapper::wrap(scope.engine, netValue);
QSharedPointer<NetVariant> netVariant = QSharedPointer<NetVariant>(new NetVariant());
netVariant->setNetReference(netReference);
return netVariant->toQVariant();
}
ReturnedValue NetObject::method_serialize(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
void JsNetObject::gcCollect(int maxGeneration)
{
QV4::Scope scope(b);
if(argc != 1) {
THROW_GENERIC_ERROR("Net.serialize(): Missing instance parameter");
}
QV4::ScopedValue instance(scope, argv[0]);
if(instance->isNullOrUndefined()) {
THROW_GENERIC_ERROR("Net.serialize(): Instance parameter must not be null or undefined");
}
QJSValue instanceJsValue(scope.engine, instance->asReturnedValue());
QSharedPointer<NetVariant> value = NetVariant::fromQJSValue(instanceJsValue);
if(value->getVariantType() != NetVariantTypeEnum_Object) {
THROW_GENERIC_ERROR("Net.serialize(): Parameter is not a .NET object");
}
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
bool serializationResult = serializeNetToString(value->getNetReference(), result);
if(!serializationResult) {
THROW_GENERIC_ERROR("Net.serialize(): Could not serialize object.");
}
return Encode(scope.engine->newString(result->getString()));
QmlNet::gcCollect(maxGeneration);
}
ReturnedValue NetObject::method_toJsArray(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
QVariant JsNetObject::toListModel(QJSValue value)
{
QV4::Scope scope(b);
if(argc != 1) {
THROW_GENERIC_ERROR("Net.toJsArray(): Missing instance parameter");
}
QV4::ScopedValue instance(scope, argv[0]);
if(instance->isNullOrUndefined()) {
THROW_GENERIC_ERROR("Net.toJsArray(): Instance parameter must not be null or undefined");
}
QJSValue instanceJsValue(scope.engine, instance->asReturnedValue());
QSharedPointer<NetVariant> value = NetVariant::fromQJSValue(instanceJsValue);
if(value->getVariantType() != NetVariantTypeEnum_Object) {
THROW_GENERIC_ERROR("Net.toJsArray(): Parameter is not a .NET object");
if(value.isNull() || value.isUndefined()) {
qWarning("Net.toListModel(): Instance parameter must not be null or undefined");
return QVariant();
}
QSharedPointer<NetReference> netReference = value->getNetReference();
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.");
QSharedPointer<NetVariant> netVaraint = NetVariant::fromQJSValue(value);
if(netVaraint->getVariantType() != NetVariantTypeEnum_Object) {
qWarning("Net.toListModel(): Parameter is not a .NET object");
return QVariant();
}
return NetArray::create(scope.engine, NetValue::forInstance(netReference));
}
ReturnedValue NetObject::method_toListModel(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
QV4::Scope scope(b);
if(argc != 1) {
THROW_GENERIC_ERROR("Net.toListModel(): Missing instance parameter");
}
QV4::ScopedValue instance(scope, argv[0]);
if(instance->isNullOrUndefined()) {
THROW_GENERIC_ERROR("Net.toListModel(): Instance parameter must not be null or undefined");
}
QJSValue instanceJsValue(scope.engine, instance->asReturnedValue());
QSharedPointer<NetVariant> value = NetVariant::fromQJSValue(instanceJsValue);
if(value->getVariantType() != NetVariantTypeEnum_Object) {
THROW_GENERIC_ERROR("Net.toListModel(): Parameter is not a .NET object");
}
QSharedPointer<NetReference> netReference = value->getNetReference();
NetListModel* listModel = NetListModel::fromReference(netReference);
NetListModel* listModel = NetListModel::fromReference(netVaraint->getNetReference());
if(listModel == nullptr) {
THROW_GENERIC_ERROR("Net.toListModel(): Parameter is not a type that can be wrapped by a list model.");
qWarning("Net.toListModel(): Parameter is not a type that can be wrapped by a list model.");
return QVariant();
}
QQmlEngine::setObjectOwnership(listModel, QQmlEngine::JavaScriptOwnership);
return QObjectWrapper::wrap(scope.engine, listModel);
return QVariant::fromValue(listModel);
}
#endif
void JsNetObject::toJsArray()
{
qWarning("Net.toJsArray(): Not supported anymore. Use Net.toListModel().");
}
void JsNetObject::await(QJSValue task, QJSValue successCallback, QJSValue failureCallback)
{
if(task.isNull() || task.isUndefined()) {
qWarning("Net.await(): No task object provided.");
return;
}
if(successCallback.isNull() || successCallback.isUndefined()) {
qWarning("Net.await(): Not success callback given");
return;
}
if(!successCallback.isCallable()) {
qWarning("Net.await(): Success callback invalid type.");
return;
}
if(!failureCallback.isNull() && !failureCallback.isUndefined()) {
if(!failureCallback.isCallable()) {
qWarning("Net.await(): Failure callback invalid type.");
return;
}
}
QSharedPointer<NetVariant> taskVariant = NetVariant::fromQJSValue(task);
if(taskVariant->getVariantType() != NetVariantTypeEnum_Object) {
qWarning("Net.await(): Task is invalid type.");
return;
}
QSharedPointer<NetVariant> successCallbackVariant = NetVariant::fromQJSValue(successCallback);
QSharedPointer<NetVariant> failureCallbackVariant = NetVariant::fromQJSValue(failureCallback);
QmlNet::awaitTask(taskVariant->getNetReference(),
successCallbackVariant->getJsValue(),
failureCallbackVariant != nullptr ? failureCallbackVariant->getJsValue() : nullptr);
}

View file

@ -1,38 +1,22 @@
#ifndef JSNETOBJECT_H
#define JSNETOBJECT_H
#include <private/qv4functionobject_p.h>
#include <QmlNet.h>
#include <QObject>
#include <QJSValue>
#include <QVariant>
namespace QV4 {
namespace Heap {
struct NetObject : Object {
void init();
};
}
struct NetObject : Object
class JsNetObject : public QObject
{
V4_OBJECT2(NetObject, Object)
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
static void method_gccollect(const BuiltinFunction *, Scope &scope, CallData *callData);
static void method_await(const BuiltinFunction *, Scope &scope, CallData *callData);
static void method_cancelTokenSource(const BuiltinFunction *, Scope &scope, CallData *callData);
static void method_serialize(const BuiltinFunction *, Scope &scope, CallData *callData);
static void method_toJsArray(const BuiltinFunction *, Scope &scope, CallData *callData);
static void method_toListModel(const BuiltinFunction *, Scope &scope, CallData *callData);
#else
static ReturnedValue method_gccollect(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_await(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_cancelTokenSource(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_serialize(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_toJsArray(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_toListModel(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
#endif
Q_OBJECT
public:
JsNetObject();
Q_INVOKABLE QString serialize(QJSValue value);
Q_INVOKABLE QVariant cancelTokenSource();
Q_INVOKABLE void gcCollect(int maxGeneration = 0);
Q_INVOKABLE QVariant toListModel(QJSValue value);
Q_INVOKABLE void toJsArray();
Q_INVOKABLE void await(QJSValue task, QJSValue successCallback, QJSValue failureCallback = QJSValue());
};
}
#endif // JSNETOBJECT_H

View file

@ -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, nullptr, result);
QmlNet::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, nullptr, newValue);
QmlNet::writeProperty(propertyInfo, instance, nullptr, newValue);
}
break;
case InvokeMetaMethod:
@ -170,7 +170,7 @@ int NetValueMetaObject::metaCall(QMetaObject::Call c, int idx, void **a)
result = QSharedPointer<NetVariant>(new NetVariant());
}
invokeNetMethod(methodInfo, instance, parameters, result);
QmlNet::invokeNetMethod(methodInfo, instance, parameters, result);
if(result != nullptr) {
NetMetaValuePack(returnType->getPrefVariantType(), result, a[0]);
@ -199,7 +199,7 @@ int NetValueMetaObject::metaCall(QMetaObject::Call c, int idx, void **a)
}
}
raiseNetSignals(instance, signalInfo->getName(), parameters);
QmlNet::raiseNetSignals(instance, signalInfo->getName(), parameters);
}
}
break;

View file

@ -12,7 +12,7 @@ class NetValueType : public NetValue
public:
NetValueType()
: NetValue(instantiateType(typeInfo), nullptr) {}
: NetValue(QmlNet::instantiateType(typeInfo), nullptr) {}
static void init(QSharedPointer<NetTypeInfo> info)
{

View file

@ -69,7 +69,10 @@ void NetVariant::setNetReference(QSharedPointer<NetReference> netReference)
QSharedPointer<NetReference> NetVariant::getNetReference()
{
return variant.value<NetReferenceQmlContainer>().netReference;
if(getVariantType() == NetVariantTypeEnum_Object) {
return variant.value<NetReferenceQmlContainer>().netReference;
}
return nullptr;
}
void NetVariant::setBool(bool value)
@ -194,7 +197,10 @@ void NetVariant::setJsValue(QSharedPointer<NetJSValue> jsValue)
QSharedPointer<NetJSValue> NetVariant::getJsValue()
{
return variant.value<NetJsValueQmlContainer>().jsValue;
if(getVariantType() == NetVariantTypeEnum_JSValue) {
return variant.value<NetJsValueQmlContainer>().jsValue;
}
return nullptr;
}
void NetVariant::clear()

View file

@ -24,14 +24,13 @@ Q_DECL_EXPORT QQmlApplicationEngineContainer* qqmlapplicationengine_create(QQmlA
ownsEngine = true;
}
QV4::ExecutionEngine* v4Engine = QQmlEnginePrivate::getV4Engine(engine);
JsNetObject* netObject = new JsNetObject();
QV4::Scope scope(v4Engine);
QV4::ScopedObject net(scope, v4Engine->memoryManager->allocObject<QV4::NetObject>());
v4Engine->globalObject->defineDefaultProperty("Net", net);;
engine->rootContext()->setContextProperty("Net", netObject);
return new QQmlApplicationEngineContainer{
engine,
netObject,
ownsEngine
};
}
@ -40,6 +39,7 @@ Q_DECL_EXPORT void qqmlapplicationengine_destroy(QQmlApplicationEngineContainer*
if(container->ownsEngine) {
delete container->qmlEngine;
}
delete container->netObject;
delete container;
}

View file

@ -3,9 +3,11 @@
#include <QmlNet.h>
#include <QQmlApplicationEngine>
#include <QmlNet/qml/JsNetObject.h>
struct QQmlApplicationEngineContainer {
QQmlApplicationEngine* qmlEngine;
JsNetObject* netObject;
bool ownsEngine;
};

View file

@ -13,7 +13,6 @@ HEADERS += \
$$PWD/QQuickStyle.h \
$$PWD/NetValueMetaObjectPacker.h \
$$PWD/QCommon.h \
$$PWD/JsNetArray.h \
$$PWD/NetListModel.h \
$$PWD/QtWebEngine.h
@ -34,11 +33,3 @@ SOURCES += \
$$PWD/QCommon.cpp \
$$PWD/NetListModel.cpp \
$$PWD/QtWebEngine.cpp
versionAtLeast(QT_VERSION, 5.11.0) {
message('511')
SOURCES += $$PWD/JsNetArray511.cpp
} else {
message('510')
SOURCES += $$PWD/JsNetArray510.cpp
}

View file

@ -1,5 +1,7 @@
#include <QmlNet/types/Callbacks.h>
namespace QmlNet {
typedef bool (*isTypeValidCb)(LPWSTR typeName);
typedef void (*createLazyTypeInfoCb)(NetTypeInfoContainer* typeInfo);
typedef void (*loadTypeInfoCb)(NetTypeInfoContainer* typeInfo);
@ -152,29 +154,31 @@ bool serializeNetToString(QSharedPointer<NetReference> instance, QSharedPointer<
new NetVariantContainer{result});
}
}
extern "C" {
Q_DECL_EXPORT void type_info_callbacks_registerCallbacks(NetTypeInfoManagerCallbacks* callbacks) {
sharedCallbacks = *callbacks;
Q_DECL_EXPORT void type_info_callbacks_registerCallbacks(QmlNet::NetTypeInfoManagerCallbacks* callbacks) {
QmlNet::sharedCallbacks = *callbacks;
}
Q_DECL_EXPORT bool type_info_callbacks_isTypeValid(LPWSTR typeName) {
return sharedCallbacks.isTypeValid(typeName);
return QmlNet::sharedCallbacks.isTypeValid(typeName);
}
Q_DECL_EXPORT void type_info_callbacks_releaseNetReferenceGCHandle(uint64_t objectId) {
sharedCallbacks.releaseNetReference(objectId);
QmlNet::sharedCallbacks.releaseNetReference(objectId);
}
Q_DECL_EXPORT void type_info_callbacks_releaseNetDelegateGCHandle(NetGCHandle* handle) {
sharedCallbacks.releaseNetDelegateGCHandle(handle);
QmlNet::sharedCallbacks.releaseNetDelegateGCHandle(handle);
}
Q_DECL_EXPORT NetReferenceContainer* type_info_callbacks_instantiateType(NetTypeInfoContainer* type) {
// The parameters have to be copied to new containers, because the callback
// will delete them.
NetTypeInfoContainer* typeCopy = new NetTypeInfoContainer{type->netTypeInfo};
return sharedCallbacks.instantiateType(typeCopy);
return QmlNet::sharedCallbacks.instantiateType(typeCopy);
}
Q_DECL_EXPORT void type_info_callbacks_invokeMethod(NetMethodInfoContainer* method, NetReferenceContainer* target, NetVariantListContainer* parameters, NetVariantContainer* result) {
@ -193,7 +197,7 @@ Q_DECL_EXPORT void type_info_callbacks_invokeMethod(NetMethodInfoContainer* meth
resultCopy = new NetVariantContainer{result->variant};
}
sharedCallbacks.invokeMethod(
QmlNet::sharedCallbacks.invokeMethod(
methodCopy,
targetCopy,
parametersCopy,

View file

@ -11,6 +11,8 @@
#include <QSharedPointer>
#include <QString>
namespace QmlNet {
bool isTypeValid(QString type);
void releaseNetReference(uint64_t objectId);
@ -37,4 +39,6 @@ void awaitTask(QSharedPointer<NetReference> target, QSharedPointer<NetJSValue> s
bool serializeNetToString(QSharedPointer<NetReference> instance, QSharedPointer<NetVariant> result);
}
#endif // NET_TYPE_INFO_MANAGER_H

View file

@ -7,7 +7,7 @@ NetDelegate::NetDelegate(NetGCHandle* gcHandle) :
}
NetDelegate::~NetDelegate() {
releaseNetDelegateGCHandle(gcHandle);
QmlNet::releaseNetDelegateGCHandle(gcHandle);
}
NetGCHandle* NetDelegate::getGCHandle() {

View file

@ -11,7 +11,7 @@ NetReference::NetReference(uint64_t objectId, QSharedPointer<NetTypeInfo> typeIn
NetReference::~NetReference()
{
releaseNetReference(objectId);
QmlNet::releaseNetReference(objectId);
}
uint64_t NetReference::getObjectId()

View file

@ -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, nullptr, result);
QmlNet::readProperty(_lengthProperty, reference, nullptr, result);
return static_cast<uint>(result->getInt());
}
@ -58,7 +58,7 @@ QSharedPointer<NetVariant> NetTypeArrayFacade_Array::getIndexed(QSharedPointer<N
parameter->setInt(static_cast<int>(index));
parameters->add(parameter);
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
invokeNetMethod(_getIndexed, reference, parameters, result);
QmlNet::invokeNetMethod(_getIndexed, reference, parameters, result);
return result;
}
@ -70,5 +70,5 @@ void NetTypeArrayFacade_Array::setIndexed(QSharedPointer<NetReference> reference
parameters->add(parameter);
parameters->add(value);
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
invokeNetMethod(_setIndexed, reference, parameters, result);
QmlNet::invokeNetMethod(_setIndexed, reference, parameters, result);
}

View file

@ -49,7 +49,7 @@ bool NetTypeArrayFacade_List::isFixed()
uint NetTypeArrayFacade_List::getLength(QSharedPointer<NetReference> reference)
{
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
readProperty(_lengthProperty, reference, nullptr, result);
QmlNet::readProperty(_lengthProperty, reference, nullptr, result);
return static_cast<uint>(result->getInt());
}
@ -58,7 +58,7 @@ QSharedPointer<NetVariant> NetTypeArrayFacade_List::getIndexed(QSharedPointer<Ne
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
QSharedPointer<NetVariant> indexParameter = QSharedPointer<NetVariant>(new NetVariant());
indexParameter->setInt(index);
readProperty(_itemProperty, reference, indexParameter, result);
QmlNet::readProperty(_itemProperty, reference, indexParameter, result);
return result;
}
@ -66,14 +66,14 @@ void NetTypeArrayFacade_List::setIndexed(QSharedPointer<NetReference> reference,
{
QSharedPointer<NetVariant> indexParameter = QSharedPointer<NetVariant>(new NetVariant());
indexParameter->setInt(static_cast<int>(index));
writeProperty(_itemProperty, reference, indexParameter, value);
QmlNet::writeProperty(_itemProperty, reference, indexParameter, value);
}
void NetTypeArrayFacade_List::push(QSharedPointer<NetReference> reference, QSharedPointer<NetVariant> value)
{
QSharedPointer<NetVariantList> parameters = QSharedPointer<NetVariantList>(new NetVariantList());
parameters->add(value);
invokeNetMethod(_addMethod, reference, parameters, nullptr);
QmlNet::invokeNetMethod(_addMethod, reference, parameters, nullptr);
}
QSharedPointer<NetVariant> NetTypeArrayFacade_List::pop(QSharedPointer<NetReference> reference)
@ -90,5 +90,5 @@ void NetTypeArrayFacade_List::deleteAt(QSharedPointer<NetReference> reference, u
QSharedPointer<NetVariant> parameter = QSharedPointer<NetVariant>(new NetVariant());
parameter->setInt(static_cast<int>(index));
parameters->add(parameter);
invokeNetMethod(_removeAtMethod, reference, parameters, nullptr);
QmlNet::invokeNetMethod(_removeAtMethod, reference, parameters, nullptr);
}

View file

@ -6,6 +6,8 @@
#include <QmlNet/types/NetTypeArrayFacade.h>
#include <QmlNetUtilities.h>
using namespace QmlNet;
NetTypeInfo::NetTypeInfo(QString fullTypeName) :
metaObject(nullptr),
_fullTypeName(fullTypeName),

View file

@ -2,6 +2,8 @@
#include <QmlNet/types/Callbacks.h>
#include <QSharedPointer>
using namespace QmlNet;
QMap<QString, QSharedPointer<NetTypeInfo>> NetTypeManager::types;
NetTypeManager::NetTypeManager() {

View file

@ -1,276 +0,0 @@
using System;
using System.Collections.Generic;
using FluentAssertions;
using Moq;
using Xunit;
namespace Qml.Net.Tests.Qml
{
public class ArrayTests
{
public class ArrayType : BaseQmlTests<ArrayType.ArrayTestsQml>
{
public class ArrayTestsQml
{
public virtual int[] GetArray()
{
return null;
}
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);
}
}
public class ListType : BaseQmlTests<ListType.ListTestsQml>
{
public class ListTestsQml
{
public virtual List<int> GetList()
{
return null;
}
public virtual void Test(object value)
{
}
}
[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);
}
[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);
}
[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);
}
[Fact]
public void Can_pop()
{
var list = new List<int>{3, 4, 6};
Mock.Setup(x => x.GetList()).Returns(list);
RunQmlTest(
"test",
@"
var array = Net.toJsArray(test.getList())
test.test(array.pop())
test.test(array.pop())
test.test(array.pop())
var t = array.pop()
test.test(typeof t)
");
Mock.Verify(x => x.GetList(), Times.Once);
Mock.Verify(x => x.Test(6), Times.Once);
Mock.Verify(x => x.Test(4), Times.Once);
Mock.Verify(x => x.Test(3), Times.Once);
Mock.Verify(x => x.Test("undefined"), Times.Once);
list.Count.Should().Be(0);
}
[Fact]
public void Can_push()
{
var list = new List<int>{3, 4, 6};
Mock.Setup(x => x.GetList()).Returns(list);
RunQmlTest(
"test",
@"
var array = Net.toJsArray(test.getList())
test.test(array.push(34))
");
Mock.Verify(x => x.GetList(), Times.Once);
Mock.Verify(x => x.Test(4), Times.Once);
list.Count.Should().Be(4);
list[3].Should().Be(34);
Mock.Reset();
list = new List<int>{3, 4, 6};
Mock.Setup(x => x.GetList()).Returns(list);
RunQmlTest(
"test",
@"
var array = Net.toJsArray(test.getList())
test.test(array.push(34,45))
");
Mock.Verify(x => x.GetList(), Times.Once);
Mock.Verify(x => x.Test(5), Times.Once);
list.Count.Should().Be(5);
list[3].Should().Be(34);
list[4].Should().Be(45);
}
}
}
}