Merge branch 'release/0.11.0'

This commit is contained in:
Paul Knopf 2020-08-01 23:37:28 -04:00
commit 663e05ab2b
151 changed files with 3629 additions and 7754 deletions

90
.all-contributorsrc Normal file
View file

@ -0,0 +1,90 @@
{
"projectName": "qmlnet",
"projectOwner": "qmlnet",
"repoType": "github",
"repoHost": "https://github.com",
"files": [
"README.md"
],
"badgeTemplate": "[![All Contributors](https://img.shields.io/badge/all_contributors-<%= contributors.length %>-orange.svg)](#contributors)",
"imageSize": 100,
"commit": true,
"commitConvention": "none",
"contributors": [
{
"login": "devmil",
"name": "Michael Lamers",
"avatar_url": "https://avatars1.githubusercontent.com/u/6693130?v=4",
"profile": "http://www.devmil.de",
"contributions": [
"code"
]
},
{
"login": "TripleWhy",
"name": "TripleWhy",
"avatar_url": "https://avatars0.githubusercontent.com/u/2760830?v=4",
"profile": "https://ymueller.de",
"contributions": [
"code"
]
},
{
"login": "MaxMommersteeg",
"name": "Max",
"avatar_url": "https://avatars3.githubusercontent.com/u/9657173?v=4",
"profile": "https://github.com/MaxMommersteeg",
"contributions": [
"code",
"doc",
"financial"
]
},
{
"login": "geigertom",
"name": "geigertom",
"avatar_url": "https://avatars0.githubusercontent.com/u/19152463?v=4",
"profile": "https://github.com/geigertom",
"contributions": [
"code"
]
},
{
"login": "jamesdavila",
"name": "James Davila",
"avatar_url": "https://avatars0.githubusercontent.com/u/1946041?v=4",
"profile": "https://github.com/jamesdavila",
"contributions": [
"code"
]
},
{
"login": "afillebrown",
"name": "Andy Fillebrown",
"avatar_url": "https://avatars2.githubusercontent.com/u/38264913?v=4",
"profile": "https://github.com/afillebrown",
"contributions": [
"code"
]
},
{
"login": "vadi2",
"name": "Vadim Peretokin",
"avatar_url": "https://avatars1.githubusercontent.com/u/110988?v=4",
"profile": "https://linkedin.com/in/vadimperetokin",
"contributions": [
"doc"
]
},
{
"login": "Juhlinus",
"name": "Linus Juhlin",
"avatar_url": "https://avatars0.githubusercontent.com/u/12988164?v=4",
"profile": "https://github.com/Juhlinus",
"contributions": [
"doc"
]
}
],
"contributorsPerLine": 7
}

3
.gitmodules vendored
View file

@ -1,3 +1,6 @@
[submodule "build/scripts/Buildary"]
path = build/scripts/Buildary
url = https://github.com/pauldotknopf/dotnet-buildary.git
[submodule "src/native/QmlNet"]
path = src/native/QmlNet
url = https://github.com/qmlnet/qmlnet-native

View file

@ -2,16 +2,23 @@ language: csharp
mono: none
matrix:
include:
- name: "Linux Qt 5.12.0"
dotnet: 2.2
- name: "Linux Qt 5.15.1"
dotnet: 3.1
os: linux
dist: xenial
- name: "OSX Qt 5.12.0"
dotnet: 2.2.101
- name: "OSX Qt 5.15.1"
dotnet: 3.1.300
os: osx
osx_image: xcode9.4
if: tag IS blank
git:
depth: false
before_install:
# to support running tests for .NET Core 2.1 LTS, install the runtime side-by-side
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get install dotnet-runtime-2.1 ; fi
# Copied from csharp.rb in the travis-build repo
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then wget --retry-connrefused --waitretry=1 -O /tmp/dotnet.pkg https://download.visualstudio.microsoft.com/download/pr/bc303f50-ec1d-43b4-b846-51d5fc3c1a2d/4f0abfa496fba6a387dc80b450eb65b8/dotnet-runtime-2.1.18-osx-x64.pkg; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then sudo installer -package "/tmp/dotnet.pkg" -target "/" -verboseR; fi
script:
- ./build/travis.sh

247
README.md
View file

@ -1,11 +1,11 @@
# Qml.Net
<p><a href="https://github.com/qmlnet/qmlnet" rel="nofollow"><img src="https://qmlnet.github.io/qmlnet.png" width="150"></a></p>
A Qml integration with .NET
[![Qml.Net](https://img.shields.io/nuget/v/Qml.Net.svg?style=flat&label=Qml.Net)](http://www.nuget.org/packages/Qml.Net/) [![Build status](https://travis-ci.com/qmlnet/qmlnet.svg?branch=develop)](https://travis-ci.com/qmlnet/qmlnet) [![Build status](https://ci.appveyor.com/api/projects/status/l0hh7ranqawj682y/branch/develop?svg=true)](https://ci.appveyor.com/project/pauldotknopf/qmlnet/) [![Gitter](https://img.shields.io/gitter/room/qmlnet/Lobby.svg?style=flat)](https://gitter.im/qmlnet/Lobby) [![All Contributors](https://img.shields.io/badge/all_contributors-8-orange.svg)](#contributors) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/pauldotknopf)
[![Qml.Net](https://img.shields.io/nuget/v/Qml.Net.svg?style=flat&label=Qml.Net)](http://www.nuget.org/packages/Qml.Net/)
[![Build status](https://travis-ci.com/qmlnet/qmlnet.svg?branch=develop)](https://travis-ci.com/qmlnet/qmlnet) [![Build status](https://ci.appveyor.com/api/projects/status/l0hh7ranqawj682y/branch/develop?svg=true)](https://ci.appveyor.com/project/pauldotknopf/qmlnet/branch/develop)
[![Gitter chat](https://img.shields.io/gitter/room/qmlnet/Lobby.svg?style=flat)](https://gitter.im/qmlnet/Lobby) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/pauldotknopf)
<hr />
A Qt/Qml integration with .NET
Supported platforms/runtimes:
* Runtimes:
@ -17,133 +17,157 @@ Supported platforms/runtimes:
* OSX
* Windows
# First look
<img src="https://github.com/pauldotknopf/Qml.Net.Examples/blob/master/assets/features.gif" alt="" style="max-width:100%;" width="200">
# Elevator pitch
* Proven in production.
* Established GUI/control framework, used in many industries, from desktop to embedded.
* Excellent community with many open-sourced controls available.
* Native rendering, done in native code. No expensive PInvoke calls for rendering/animations/etc. The only interop between .NET and Qt is the data models used to drive the GUI.
# Documentation
https://qmlnet.github.io/
WIP: https://qmlnet.github.io/
# Getting started
```bash
dotnet add package Qml.Net
```
**Windows**
```bash
dotnet add package Qml.Net.WindowsBinaries
```
**OSX**
```bash
dotnet add package Qml.Net.OSXBinaries
```
**Linux**
```bash
dotnet add package Qml.Net.LinuxBinaries
```
```
Checkout the [examples](https://github.com/qmlnet/qmlnet-examples) for some inspiration.
**Note for Linux users**: Package `libc6-dev` is required to be installed because it contains `libdl.so` that is needed.
# Examples
Checkout the [examples](https://github.com/qmlnet/qmlnet-examples) on how to do many things with Qml.Net.
# Quick overview
**Define a .NET type (POCO)**
```c#
[Signal("customSignal", NetVariantType.String)] // You can define signals that Qml can listen to.
public class QmlType
//QmlType.cs
using Qml.Net;
using System.Threading.Tasks;
namespace QmlQuickOverview
{
/// <summary>
/// Properties are exposed to Qml.
/// </summary>
[NotifySignal("stringPropertyChanged")] // For Qml binding/MVVM.
public string StringProperty { get; set; }
[Signal("customSignal", NetVariantType.String)] // You can define signals that Qml can listen to.
public class QmlType
{
/// <summary>
/// Properties are exposed to Qml.
/// </summary>
[NotifySignal("stringPropertyChanged")] // For Qml binding/MVVM.
public string StringProperty { get; set; }
/// <summary>
/// Methods can return .NET types.
/// The returned type can be invoked from Qml (properties/methods/events/etc).
/// </summary>
/// <returns></returns>
public QmlType CreateNetObject()
{
return new QmlType();
}
/// <summary>
/// Qml can pass .NET types to .NET methods.
/// </summary>
/// <param name="parameter"></param>
public void TestMethod(QmlType parameter)
{
}
/// <summary>
/// Async methods can be invoked with continuations happening on Qt's main thread.
/// </summary>
public async Task<string> TestAsync()
{
// On the UI thread
await Task.Run(() =>
/// <summary>
/// Methods can return .NET types.
/// The returned type can be invoked from Qml (properties/methods/events/etc).
/// </summary>
/// <returns></returns>
public QmlType CreateNetObject()
{
// On the background thread
});
// On the UI thread
return "async result!"
}
/// <summary>
/// Qml can also pass Qml/C++ objects that can be invoked from .NET
/// </summary>
/// <param name="qObject"></param>
public void TestMethodWithQObject(dynamic o)
{
string result = o.PropertyDefinedInCpp;
o.MethodDefinedInCpp(result);
return new QmlType();
}
/// <summary>
/// Qml can pass .NET types to .NET methods.
/// </summary>
/// <param name="parameter"></param>
public void TestMethod(QmlType parameter)
{
}
// You can also listen to signals on QObjects.
var qObject = o as INetQObject.
var handler = qObject.AttachSignal("signalName", parameters => {
// parameters is a list of arguements passed to the signal.
});
handle.Dispose() // When you are done listening to signal.
/// <summary>
/// Async methods can be invoked with continuations happening on Qt's main thread.
/// </summary>
public async Task<string> TestAsync()
{
// On the UI thread
await Task.Run(() =>
{
// On the background thread
});
// On the UI thread
return "async result!";
}
// You can also listen to when a property changes (notify signal).
var handler = qObject.AttachNotifySignal("propertySignal", parameters => {
// parameters is a list of arguements passed to the signal.
});
handle.Dispose() // When you are done listening to signal.
}
/// <summary>
/// .NET can activate signals to send notifications to Qml.
/// </summary>
public void ActivateCustomSignal(string message)
{
this.ActivateSignal("customSignal", message)
/// <summary>
/// Qml can also pass Qml/C++ objects that can be invoked from .NET
/// </summary>
/// <param name="qObject"></param>
public void TestMethodWithQObject(dynamic o)
{
string result = o.propertyDefinedInCpp;
o.methodDefinedInCpp(result);
// You can also listen to signals on QObjects.
var qObject = o as INetQObject;
var handler = qObject.AttachSignal("signalName", parameters => {
// parameters is a list of arguements passed to the signal.
});
handler.Dispose(); // When you are done listening to signal.
// You can also listen to when a property changes (notify signal).
handler = qObject.AttachNotifySignal("property", parameters => {
// parameters is a list of arguements passed to the signal.
});
handler.Dispose(); // When you are done listening to signal.
}
/// <summary>
/// .NET can activate signals to send notifications to Qml.
/// </summary>
public void ActivateCustomSignal(string message)
{
this.ActivateSignal("customSignal", message);
}
}
}
```
**Register your new type with Qml.**
```c#
using (var app = new QGuiApplication(args))
//QmlExample.cs
using Qml.Net;
using Qml.Net.Runtimes;
namespace QmlQuickOverview
{
using (var engine = new QQmlApplicationEngine())
class QmlExample
{
// Register our new type to be used in Qml
QQmlApplicationEngine.RegisterType<QmlType>("test", 1, 1);
engine.Load("main.qml");
return app.Exec();
static int Main(string[] args)
{
RuntimeManager.DiscoverOrDownloadSuitableQtRuntime();
using (var app = new QGuiApplication(args))
{
using (var engine = new QQmlApplicationEngine())
{
// Register our new type to be used in Qml
Qml.Net.Qml.RegisterType<QmlType>("test", 1, 1);
engine.Load("Main.qml");
return app.Exec();
}
}
}
}
}
```
**Use the .NET type in Qml**
```js
//Main.qml
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
@ -205,8 +229,35 @@ ApplicationWindow {
- [x] Dynamically compiled delegates for increased performance.
- [x] Passing ```QObject``` types to .NET with support for interacting with signals/slots/properties on them.
# Not implemented (but planned)
There aren't really any important features missing that are needed for prime-time. This product is currently used on embedded devices in the medical industry.
- [ ] Compiling Qml resource files and bundling them within .NET.
- [ ] .NET Events to signals
- [ ] Qml debugger for VS and VS Code.
# Running Unit Tests
The unit tests can be found in [src/native/Qml.Net.Tests](src/net/Qml.Net.Tests).
They can be run directly from Visual Studio, or by using the `dotnet test` command line tool.
Since the tests rely on the native QmlNet library, you have to ensure the library is in the `PATH` (on Windows) or otherwise discoverable. If you are trying to run tests against the native library built from the same repository, you can put the `src/native/output` folder into your `PATH` or `LD_LIBRARY_PATH` after running the `build.bat` or `build.sh` script.
## Contributors ✨
Thanks goes to these wonderful people!
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore -->
<table>
<tr>
<td align="center"><a href="http://www.devmil.de"><img src="https://avatars1.githubusercontent.com/u/6693130?v=4" width="100px;" alt="Michael Lamers"/><br /><sub><b>Michael Lamers</b></sub></a><br /><a href="https://github.com/qmlnet/qmlnet/commits?author=devmil" title="Code">💻</a></td>
<td align="center"><a href="https://ymueller.de"><img src="https://avatars0.githubusercontent.com/u/2760830?v=4" width="100px;" alt="TripleWhy"/><br /><sub><b>TripleWhy</b></sub></a><br /><a href="https://github.com/qmlnet/qmlnet/commits?author=TripleWhy" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/MaxMommersteeg"><img src="https://avatars3.githubusercontent.com/u/9657173?v=4" width="100px;" alt="Max"/><br /><sub><b>Max</b></sub></a><br /><a href="https://github.com/qmlnet/qmlnet/commits?author=MaxMommersteeg" title="Code">💻</a> <a href="https://github.com/qmlnet/qmlnet/commits?author=MaxMommersteeg" title="Documentation">📖</a> <a href="#financial-MaxMommersteeg" title="Financial">💵</a></td>
<td align="center"><a href="https://github.com/geigertom"><img src="https://avatars0.githubusercontent.com/u/19152463?v=4" width="100px;" alt="geigertom"/><br /><sub><b>geigertom</b></sub></a><br /><a href="https://github.com/qmlnet/qmlnet/commits?author=geigertom" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/jamesdavila"><img src="https://avatars0.githubusercontent.com/u/1946041?v=4" width="100px;" alt="James Davila"/><br /><sub><b>James Davila</b></sub></a><br /><a href="https://github.com/qmlnet/qmlnet/commits?author=jamesdavila" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/afillebrown"><img src="https://avatars2.githubusercontent.com/u/38264913?v=4" width="100px;" alt="Andy Fillebrown"/><br /><sub><b>Andy Fillebrown</b></sub></a><br /><a href="https://github.com/qmlnet/qmlnet/commits?author=afillebrown" title="Code">💻</a></td>
<td align="center"><a href="https://linkedin.com/in/vadimperetokin"><img src="https://avatars1.githubusercontent.com/u/110988?v=4" width="100px;" alt="Vadim Peretokin"/><br /><sub><b>Vadim Peretokin</b></sub></a><br /><a href="https://github.com/qmlnet/qmlnet/commits?author=vadi2" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/Juhlinus"><img src="https://avatars0.githubusercontent.com/u/12988164?v=4" width="100px;" alt="Linus Juhlin"/><br /><sub><b>Linus Juhlin</b></sub></a><br /><a href="https://github.com/qmlnet/qmlnet/commits?author=Juhlinus" title="Documentation">📖</a></td>
</tr>
</table>
<!-- ALL-CONTRIBUTORS-LIST:END -->

View file

@ -1,10 +1,10 @@
image: Visual Studio 2017
image: Visual Studio 2019
before_build:
- ps: Invoke-WebRequest -Uri https://github.com/qmlnet/qt-runtimes/releases/download/releases/qt-5.12.2-ad0689c-win-x64-dev.tar.gz -OutFile C:\qmlnet-qt.tar.gz
- ps: Invoke-WebRequest -Uri https://github.com/qmlnet/qt-runtimes/releases/download/releases/qt-5.15.1-7fc8b10-win-x64-dev.tar.gz -OutFile C:\qmlnet-qt.tar.gz
- cmd: 7z x C:\qmlnet-qt.tar.gz -oC:\
- cmd: 7z x C:\qmlnet-qt.tar -oC:\qmlnet-qt
- cmd: rm -r C:\Tools\GitVersion\
- cmd: dotnet tool install -g GitVersion.Tool --version 4.0.1-beta1-58
- cmd: dotnet tool install -g GitVersion.Tool --version 5.3.4
- cmd: dotnet gitversion > version.json
- cmd: git submodule update --init
build_script:

View file

@ -1,4 +1,4 @@
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
set PATH=%PATH%;C:\qmlnet-qt\qt\bin
set PATH=%PATH%;C:\qmlnet-qt\Tools\QtCreator\bin

View file

@ -1,3 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<Import Project="Buildary\Build.proj" />
</Project>
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
</Project>

@ -1 +1 @@
Subproject commit 02b50181ced2459ec3f5f7ee2cce1ffad4fe01b3
Subproject commit 6df06b3ffa16f164adc18f8064917bf0c1a1229b

View file

@ -18,14 +18,14 @@ namespace Build
{
static class Program
{
static Task Main(string[] args)
static void Main(string[] args)
{
var options = ParseOptions<Options>(args);
var options = ParseOptions<RunnerOptions>(args);
var nugetApiKey = Environment.GetEnvironmentVariable("PRIVATE_NUGET_KEY");
var nugetSource = "https://www.myget.org/F/qmlnet/api/v3/index.json";
var gitversion = GetGitVersion(ExpandPath("./"));
var commandBuildArgs = $"--configuration {options.Configuration} /p:Platform=\"Any CPU\"";
var commandBuildArgs = $"--configuration {options.Config} /p:Platform=\"Any CPU\"";
var commandBuildArgsWithVersion = commandBuildArgs;
if (!string.IsNullOrEmpty(gitversion.PreReleaseTag))
{
@ -139,15 +139,7 @@ namespace Build
Target("ci", DependsOn("update-version", "build", "test", "deploy", "publish"));
return Run(options);
}
// ReSharper disable ClassNeverInstantiated.Local
class Options : RunnerOptions
// ReSharper restore ClassNeverInstantiated.Local
{
[PowerArgs.ArgShortcut("config"), PowerArgs.ArgDefaultValue("Release")]
public string Configuration { get; set; }
Execute(options);
}
}
}

View file

@ -1,12 +1,14 @@
#!/usr/bin/env bash
set -x
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
QT_DIR=$SCRIPT_DIR/Qt
sudo apt-get install -y libgl1-mesa-dev
mkdir -p $QT_DIR
wget -O- -q https://github.com/qmlnet/qt-runtimes/releases/download/releases/qt-5.12.2-ad0689c-linux-x64-dev.tar.gz | tar xpz -C $QT_DIR
wget -O- -q https://github.com/qmlnet/qt-runtimes/releases/download/releases/qt-5.15.1-7fc8b10-linux-x64-dev.tar.gz | tar xpz -C $QT_DIR
export PATH=$QT_DIR/qt/bin:$PATH
export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/src/native/output:$QT_DIR/qt/lib

View file

@ -5,7 +5,7 @@ SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
QT_DIR=$SCRIPT_DIR/Qt
mkdir -p $QT_DIR
wget -O- -q https://github.com/qmlnet/qt-runtimes/releases/download/releases/qt-5.12.2-ad0689c-osx-x64-dev.tar.gz | tar xpz -C $QT_DIR
wget -O- -q https://github.com/qmlnet/qt-runtimes/releases/download/releases/qt-5.15.1-7fc8b10-osx-x64-dev.tar.gz | tar xpz -C $QT_DIR
export PATH=$QT_DIR/qt/bin:$PATH
export DYLD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/src/native/output:$QT_DIR/qt/lib

View file

@ -1,10 +1,11 @@
#!/usr/bin/env bash
set -e
set -x
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
# Before we run the build, get gitversion and generate a version.json.
dotnet tool install -g GitVersion.Tool --version 4.0.1-beta1-58
dotnet tool install -g GitVersion.Tool --version 5.3.4
export PATH="$PATH:$HOME/.dotnet/tools"
dotnet gitversion > version.json

View file

@ -28,7 +28,7 @@ namespace NetHost
// Phase 6
// Register any .NET types that will be used.
QQmlApplicationEngine.RegisterType<TestObject>("test");
Qml.Net.Qml.RegisterType<TestObject>("test", 1, 0);
// Phase 7
// This callback passes control back to C++ to perform

1
src/native/QmlNet Submodule

@ -0,0 +1 @@
Subproject commit e2ff96713b659ed295710f4e94cef96b2f7e020a

View file

@ -1,23 +0,0 @@
INCLUDEPATH += $$PWD
HEADERS += $$PWD/Hosting/coreclrhost.h \
$$PWD/Hosting/CoreHost.h
SOURCES += \
$$PWD/Hosting/CoreHost.cpp
unix {
LIBS += -ldl
}
# These settings are needed to get symbols
# for the current running process.
macx {
# nothing needed for OSX
}
unix:!macx {
QMAKE_LFLAGS += -fPIC -rdynamic
}
win32 {
QMAKE_LFLAGS += /FIXED:NO
}

View file

@ -1,222 +0,0 @@
#include <Hosting/CoreHost.h>
#include <Hosting/coreclrhost.h>
#include <QFileInfo>
#include <QDir>
#include <QDirIterator>
#include <QVersionNumber>
#ifdef _WIN32
#include <Windows.h>
#else
#include <dlfcn.h>
#endif
#ifdef __APPLE__
#define HOSTFXR_DLL_NAME "libhostfxr.dylib"
#elif _WIN32
#define HOSTFXR_DLL_NAME "hostfxr.dll"
#else
#define HOSTFXR_DLL_NAME "libhostfxr.so"
#endif
static QString nativeModule;
static void* getExportedFunction(const char* symbolName) {
#ifdef _WIN32
HMODULE library = GetModuleHandle(nativeModule.isNull() || nativeModule.isEmpty() ? nullptr
: nativeModule.toLocal8Bit());
FARPROC symbol = GetProcAddress(library, symbolName);
return (void*)symbol;
#else
void* dll = dlopen(nativeModule.isNull() || nativeModule.isEmpty() ? nullptr : nativeModule.toLocal8Bit(),
RTLD_LAZY);
void* result = dlsym(dll, symbolName);
dlclose(dll);
return result;
#endif
}
QList<QString> CoreHost::getPotientialDotnetRoots()
{
QList<QString> result;
#ifdef _WIN32
result.push_back("C:\\Program Files\\dotnet");
#else
result.push_back("/usr/local/share/dotnet");
result.push_back("/usr/share/dotnet");
result.push_back("/opt/dotnet");
#endif
QByteArray dotnetRoot = qgetenv("DOTNET_ROOT");
if(!dotnetRoot.isEmpty()) {
// We are overriding the roots, forcing ourselves to look in a particular spot.
result.clear();
result.push_back(dotnetRoot);
}
return result;
}
CoreHost::HostFxrContext CoreHost::findHostFxr()
{
HostFxrContext result;
result.success = false;
QList<QString> roots = getPotientialDotnetRoots();
for(QString root : roots) {
qDebug("looking for %s in root %s", HOSTFXR_DLL_NAME, qPrintable(root));
if(!root.endsWith(QDir::separator())) {
root.append(QDir::separator());
}
QFileInfo rootInfo(root);
if(!rootInfo.exists()) {
qDebug("%s doesn't exist", qPrintable(rootInfo.path()));
continue;
}
QString host = root;
host.append("host");
host.append(QDir::separator());
QFileInfo hostInfo(host);
if(!hostInfo.exists()) {
qDebug("%s doesn't exist", qPrintable(host));
continue;
}
QString fxr = host;
fxr.append("fxr");
fxr.append(QDir::separator());
QFileInfo fxrInfo(fxr);
if(!fxrInfo.exists()) {
qDebug("%s doesn't exist.", qPrintable(fxr));
continue;
}
QString currentFxrLib;
QVersionNumber currentFxrLibVersion;
QDir fxrDir = fxrInfo.dir();
fxrDir.setFilter(QDir::Dirs | QDir::NoDot | QDir::NoDotDot);
QDirIterator it(fxrDir, QDirIterator::Subdirectories);
while(it.hasNext()) {
QString fxrVersion = it.next();
QFileInfo fxrVersionInfo(fxrVersion);
fxrVersion.append(QDir::separator());
fxrVersion.append(HOSTFXR_DLL_NAME);
QFileInfo fxrLibInfo(fxrVersion);
if(!fxrLibInfo.exists()) {
qDebug("%s doesn't exist", qPrintable(fxrLibInfo.absoluteFilePath()));
continue;
}
QVersionNumber version = QVersionNumber::fromString(fxrVersionInfo.fileName());
if(currentFxrLibVersion.isNull() || version > currentFxrLibVersion) {
qDebug("found potentional file %s with version %s", qPrintable(fxrLibInfo.absoluteFilePath()), qPrintable((version.toString())));
currentFxrLibVersion = version;
currentFxrLib = fxrLibInfo.absoluteFilePath();
} else {
qDebug("ignore file %s with version %s", qPrintable(fxrLibInfo.absoluteFilePath()), qPrintable((version.toString())));
}
}
if(!currentFxrLib.isEmpty()) {
qDebug("returning hostfx lib: %s", qPrintable(currentFxrLib));
result.success = true;
result.hostFxrLib = currentFxrLib;
result.dotnetRoot = root;
return result;
}
}
return result;
}
int CoreHost::run(QGuiApplication& app, QQmlApplicationEngine& engine, runCallback runCallback, RunContext runContext)
{
nativeModule = runContext.nativeModule;
QList<QString> execArgs;
execArgs.push_back(runContext.entryPoint);
execArgs.push_back("exec");
execArgs.push_back(runContext.managedExe);
QString appPtr;
appPtr.sprintf("%llu", (quintptr)&app);
QString enginePtr;
enginePtr.sprintf("%llu", (quintptr)&engine);
QString callbackPtr;
callbackPtr.sprintf("%llu", (quintptr)runCallback);
QString exportedSymbolPointer;
exportedSymbolPointer.sprintf("%llu", (quintptr)getExportedFunction);
execArgs.push_back(appPtr);
execArgs.push_back(enginePtr);
execArgs.push_back(callbackPtr);
execArgs.push_back(exportedSymbolPointer);
for (QString arg : runContext.args) {
execArgs.push_back(arg);
}
std::vector<const CORECLR_CHAR_TYPE*> hostFxrArgs;
#ifdef _WIN32
for (QString arg : execArgs) {
hostFxrArgs.push_back(arg.utf16());
}
#else
QList<QByteArray> execArgs8bit;
for (QString arg : execArgs) {
execArgs8bit.push_back(arg.toLocal8Bit());
}
for (QByteArray arg : execArgs8bit) {
hostFxrArgs.push_back(arg);
}
#endif
hostfxr_main_ptr hostfxr_main = nullptr;
#ifdef _WIN32
HMODULE dll = LoadLibraryA(qPrintable(runContext.hostFxrContext.hostFxrLib));
if(dll == nullptr) {
qCritical("Couldn't load lib at %s", qPrintable(runContext.hostFxrContext.hostFxrLib));
return LoadHostFxrResult::Failed;
}
hostfxr_main = reinterpret_cast<hostfxr_main_ptr>(GetProcAddress(dll, "hostfxr_main"));
#else
void* dll = dlopen(qPrintable(runContext.hostFxrContext.hostFxrLib), RTLD_NOW | RTLD_LOCAL);
if(dll == nullptr) {
qCritical("Couldn't load lib at %s", qPrintable(runContext.hostFxrContext.hostFxrLib));
return LoadHostFxrResult::Failed;
}
hostfxr_main = reinterpret_cast<hostfxr_main_ptr>(dlsym(dll, "hostfxr_main"));
#endif
if(hostfxr_main == nullptr) {
qCritical("Couldn't load 'hostfxr_main' from %s", qPrintable(runContext.hostFxrContext.hostFxrLib));
return -1;
}
int result = hostfxr_main(static_cast<int>(hostFxrArgs.size()), &hostFxrArgs[0]);
#ifdef _WIN32
FreeLibrary(dll);
#else
dlclose(dll);
#endif
return result;
}

View file

@ -1,45 +0,0 @@
#ifndef COREHOST_H
#define COREHOST_H
#include <QSharedPointer>
#include <Hosting/coreclrhost.h>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#ifdef _WIN32
#define CORECLR_DOTNET_EXE_NAME "dotnet.exe"
#else
#define CORECLR_DOTNET_EXE_NAME "dotnet"
#endif
class CoreHost : public QObject
{
Q_OBJECT
public:
struct HostFxrContext {
bool success;
QString dotnetRoot;
QString hostFxrLib;
};
struct RunContext {
HostFxrContext hostFxrContext;
QString entryPoint;
QString managedExe;
QList<QString> args;
QString nativeModule;
};
enum LoadHostFxrResult
{
Loaded,
AlreadyLoaded,
Failed
};
typedef int (*runCallback)(QGuiApplication* app, QQmlApplicationEngine* engine);
static QList<QString> getPotientialDotnetRoots();
static HostFxrContext findHostFxr();
static int run(QGuiApplication& app, QQmlApplicationEngine& engine, runCallback runCallback, RunContext runContext);
};
#endif

View file

@ -1,80 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// APIs for hosting CoreCLR
//
#ifndef CORECLR_HOST_H
#define CORECLR_HOST_H
#ifdef _WIN32
typedef unsigned short CORECLR_CHAR_TYPE;
#else
typedef char CORECLR_CHAR_TYPE;
#endif
// For each hosting API, we define a function prototype and a function pointer
// The prototype is useful for implicit linking against the dynamic coreclr
// library and the pointer for explicit dynamic loading (dlopen, LoadLibrary)
#define CORECLR_HOSTING_API(function, ...) \
extern "C" int function(__VA_ARGS__); \
typedef int (*function##_ptr)(__VA_ARGS__)
CORECLR_HOSTING_API(coreclr_initialize,
const char* exePath,
const char* appDomainFriendlyName,
int propertyCount,
const char** propertyKeys,
const char** propertyValues,
void** hostHandle,
unsigned int* domainId);
CORECLR_HOSTING_API(coreclr_shutdown,
void* hostHandle,
unsigned int domainId);
CORECLR_HOSTING_API(coreclr_shutdown_2,
void* hostHandle,
unsigned int domainId,
int* latchedExitCode);
CORECLR_HOSTING_API(coreclr_create_delegate,
void* hostHandle,
unsigned int domainId,
const char* entryPointAssemblyName,
const char* entryPointTypeName,
const char* entryPointMethodName,
void** delegate);
CORECLR_HOSTING_API(coreclr_execute_assembly,
void* hostHandle,
unsigned int domainId,
int argc,
const char** argv,
const char* managedAssemblyPath,
unsigned int* exitCode);
// hostfxr
CORECLR_HOSTING_API(hostfxr_get_native_search_directories,
const int argc,
const char* argv[],
char buffer[],
int buffer_size,
int* required_buffer_size);
CORECLR_HOSTING_API(hostfxr_main_startupinfo,
const int argc,
const char* argv[],
const char* host_path,
const char* dotnet_root,
const char* app_path);
CORECLR_HOSTING_API(hostfxr_main,
const int argc,
const CORECLR_CHAR_TYPE* argv[]);
#undef CORECLR_HOSTING_API
#endif // CORECLR_HOST_H

View file

@ -1,11 +0,0 @@
#include <QmlNet.h>
extern "C" {
long Q_DECL_EXPORT qml_net_getVersion()
{
// TODO: Return a proper version
return 0;
}
}

View file

@ -1,57 +0,0 @@
#ifndef QMLNET_GLOBAL_H
#define QMLNET_GLOBAL_H
#include <QtCore/qglobal.h>
#define NetGCHandle void
#if _MSC_VER
typedef const wchar_t* BCSTR;
typedef const char* LPCSTR;
typedef const char16_t* LPWCSTR;
typedef char16_t* LPWSTR;
#endif
#if !_MSC_VER
#define __declspec(dllexport)
#define __stdcall
typedef char16_t* BSTR;
typedef const char16_t* BCSTR;
typedef char* LPSTR;
typedef const char* LPCSTR;
typedef char16_t* LPWSTR;
typedef const char16_t* LPWCSTR;
#if UNICODE
#define LPTSTR(value) (LPTSTR)u ##value;
typedef LPWSTR LPTSTR;
typedef LPWCSTR LPTCSTR;
#else
#define LPTSTR(value) value;
typedef LPSTR LPTSTR;
typedef LPCSTR LPTCSTR;
#endif
#endif
enum NetVariantTypeEnum {
NetVariantTypeEnum_Invalid = 0,
NetVariantTypeEnum_Bool,
NetVariantTypeEnum_Char,
NetVariantTypeEnum_Int,
NetVariantTypeEnum_UInt,
NetVariantTypeEnum_Long,
NetVariantTypeEnum_ULong,
NetVariantTypeEnum_Float,
NetVariantTypeEnum_Double,
NetVariantTypeEnum_String,
NetVariantTypeEnum_DateTime,
NetVariantTypeEnum_Object,
NetVariantTypeEnum_JSValue,
NetVariantTypeEnum_QObject
};
#endif // QMLNET_GLOBAL_H

View file

@ -1,22 +0,0 @@
QT += gui qml core-private quickcontrols2 widgets testlib
CONFIG(enable-webengine) {
QT += webengine
DEFINES += QMLNET_WEBENGINE
}
CONFIG(qmlnet-trace) {
DEFINES += QMLNET_TRACE
}
INCLUDEPATH += $$PWD
HEADERS += $$PWD/QmlNet.h \
$$PWD/QmlNetUtilities.h
include (QmlNet/types/types.pri)
include (QmlNet/qml/qml.pri)
SOURCES += \
$$PWD/QmlNet.cpp \
$$PWD/QmlNetUtilities.cpp

View file

@ -1,19 +0,0 @@
#-------------------------------------------------
#
# Project created by QtCreator 2017-05-31T14:08:15
#
#-------------------------------------------------
CONFIG += c++11
CONFIG += plugin
TARGET = QmlNet
TEMPLATE = lib
DEFINES += QMLNET_LIBRARY
DEFINES += QT_DEPRECATED_WARNINGS
include(QmlNet.pri)
target.path = $$(PREFIX)/
INSTALLS += target

View file

@ -1,333 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.6.2, 2018-07-20T23:12:28. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{e94916b6-9204-4c46-abdd-7020f311ebbb}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.11.1 clang 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.11.1 clang 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5111.clang_64_kit</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/pknopf/Git/net-core-qml/src/native/build-QtNetCoreQml-Desktop_Qt_5_11_1_clang_64bit-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/pknopf/Git/net-core-qml/src/native/build-QtNetCoreQml-Desktop_Qt_5_11_1_clang_64bit-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/pknopf/Git/net-core-qml/src/native/build-QtNetCoreQml-Desktop_Qt_5_11_1_clang_64bit-Profile</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">true</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Profile</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy Configuration</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Arguments">/Users/pknopf/git/net-core-qml/src/net/Qt.NetCore.Sandbox/bin/Debug/netcoreapp2.2/Qt.NetCore.Sandbox.dll</value>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">/usr/local/share/dotnet/dotnet</value>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory">/Users/pknopf/git/net-core-qml/src/net/Qt.NetCore.Sandbox</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run /usr/local/share/dotnet/dotnet</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">18</value>
</data>
<data>
<variable>Version</variable>
<value type="int">18</value>
</data>
</qtcreator>

View file

@ -1,165 +0,0 @@
#include <QmlNet/qml/JsNetObject.h>
#include <QmlNet/qml/NetVariant.h>
#include <QmlNet/types/Callbacks.h>
#include <QmlNet/types/NetTypeManager.h>
#include <QmlNet/types/NetTypeArrayFacade.h>
#include <QmlNet/qml/NetListModel.h>
#include <QmlNet/qml/QQmlApplicationEngine.h>
#include <QQmlEngine>
#include <QDebug>
JsNetObject::JsNetObject() = default;
QString JsNetObject::serialize(const QJSValue& value)
{
if(value.isNull() || value.isUndefined()) {
qWarning() << "Net.serialize(): Instance parameter must not be null or undefined";
return QString();
}
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(new NetVariant());
bool serializationResult = QmlNet::serializeNetToString(netVaraint->getNetReference(), result);
if(!serializationResult) {
qWarning() << "Net.serialize(): Could not serialize object.";
return QString();
}
return result->getString();
}
QVariant JsNetObject::cancelTokenSource()
{
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 QVariant();
}
QSharedPointer<NetReference> netReference = QmlNet::instantiateType(typeInfo);
if(netReference == nullptr) {
qWarning() << "Couldn't create cancellation token for platform, please file a bug";
return QVariant();
}
QSharedPointer<NetVariant> netVariant(new NetVariant());
netVariant->setNetReference(netReference);
return netVariant->toQVariant();
}
void JsNetObject::gcCollect(int maxGeneration)
{
QmlNet::gcCollect(maxGeneration);
}
QVariant JsNetObject::toListModel(const QJSValue& value)
{
if(value.isNull() || value.isUndefined()) {
qWarning() << "Net.toListModel(): Instance parameter must not be null or undefined";
return QVariant();
}
QSharedPointer<NetVariant> netVaraint = NetVariant::fromQJSValue(value);
if(netVaraint->getVariantType() != NetVariantTypeEnum_Object) {
qWarning() << "Net.toListModel(): Parameter is not a .NET object";
return QVariant();
}
NetListModel* listModel = NetListModel::fromReference(netVaraint->getNetReference());
if(listModel == nullptr) {
qWarning() << "Net.toListModel(): Parameter is not a type that can be wrapped by a list model.";
return QVariant();
}
QQmlEngine::setObjectOwnership(listModel, QQmlEngine::JavaScriptOwnership);
return QVariant::fromValue(listModel);
}
Q_INVOKABLE QVariant JsNetObject::listForEach(const QJSValue& value, QJSValue callback)
{
if(value.isNull() || value.isUndefined()) {
qWarning() << "Net.listForEach(): Instance parameter must not be null or undefined";
return QVariant();
}
if(callback.isNull() || callback.isUndefined()) {
qWarning() << "Net.listForEach(): Callback must not be null or undefined";
return QVariant();
}
if(!callback.isCallable()) {
qWarning() << "Net.listForEach(): Callback is not a function";
return QVariant();
}
QSharedPointer<NetVariant> netVaraint = NetVariant::fromQJSValue(value);
if(netVaraint->getVariantType() != NetVariantTypeEnum_Object) {
qWarning() << "Net.listForEach(): Parameter is not a .NET object";
return QVariant();
}
QSharedPointer<NetReference> netReference = netVaraint->getNetReference();
QSharedPointer<NetTypeArrayFacade> facade = netReference->getTypeInfo()->getArrayFacade();
if(facade == nullptr) {
qWarning() << "Net.listForEach(): Parameter is not a type that be enumerated.";
return QVariant();
}
uint count = facade->getLength(netReference);
for(uint x = 0; x < count; x++) {
QSharedPointer<NetVariant> item = facade->getIndexed(netReference, x);
QJSValueList args;
args.push_back(item->toQJSValue());
args.push_back(sharedQmlEngine()->toScriptValue<QVariant>(QVariant::fromValue(x)));
callback.call(args);
}
return QVariant::fromValue(count);
}
void JsNetObject::toJsArray()
{
qWarning() << "Net.toJsArray(): Not supported anymore. Use Net.toListModel().";
}
void JsNetObject::await(const QJSValue& task, const QJSValue& successCallback, const 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,23 +0,0 @@
#ifndef JSNETOBJECT_H
#define JSNETOBJECT_H
#include <QmlNet.h>
#include <QObject>
#include <QJSValue>
#include <QVariant>
class JsNetObject : public QObject
{
Q_OBJECT
public:
JsNetObject();
Q_INVOKABLE QString serialize(const QJSValue& value);
Q_INVOKABLE QVariant cancelTokenSource();
Q_INVOKABLE void gcCollect(int maxGeneration = 0);
Q_INVOKABLE QVariant toListModel(const QJSValue& value);
Q_INVOKABLE QVariant listForEach(const QJSValue& value, QJSValue callback);
Q_INVOKABLE void toJsArray();
Q_INVOKABLE void await(const QJSValue& task, const QJSValue& successCallback, const QJSValue& failureCallback = QJSValue());
};
#endif // JSNETOBJECT_H

View file

@ -1,147 +0,0 @@
#include <QmlNet/qml/NetJsValue.h>
#include <QmlNet/qml/NetVariant.h>
#include <QmlNet/qml/NetVariantList.h>
#include <QmlNet/qml/NetValue.h>
#include <QmlNet/qml/NetJsValue.h>
#include <QDebug>
#include <QJSEngine>
#include <utility>
NetJSValue::NetJSValue(QJSValue jsValue) :
_jsValue(std::move(jsValue))
{
}
NetJSValue::~NetJSValue()
{
_jsValue.isCallable();
}
QJSValue NetJSValue::getJsValue()
{
return _jsValue;
}
bool NetJSValue::isCallable() const
{
return _jsValue.isCallable();
}
bool NetJSValue::isArray() const
{
return _jsValue.isArray();
}
QSharedPointer<NetVariant> NetJSValue::call(const QSharedPointer<NetVariantList>& parameters)
{
QJSValueList jsValueList;
if(parameters != nullptr) {
for(int x = 0; x < parameters->count(); x++) {
QSharedPointer<NetVariant> netVariant = parameters->get(x);
jsValueList.append(netVariant->toQJSValue());
}
}
return NetVariant::fromQJSValue(_jsValue.call(jsValueList));
}
QSharedPointer<NetVariant> NetJSValue::getProperty(const QString& propertyName)
{
QJSValue property = _jsValue.property(propertyName);
return NetVariant::fromQJSValue(property);
}
QSharedPointer<NetVariant> NetJSValue::getItemAtIndex(quint32 arrayIndex)
{
QJSValue property = _jsValue.property(arrayIndex);
return NetVariant::fromQJSValue(property);
}
void NetJSValue::setProperty(const QString& propertyName, const QSharedPointer<NetVariant>& variant)
{
QJSValue value = QJSValue::NullValue;
if(variant != nullptr) {
value = variant->toQJSValue();
}
_jsValue.setProperty(propertyName, value);
}
void NetJSValue::setItemAtIndex(quint32 arrayIndex, const QSharedPointer<NetVariant>& variant)
{
QJSValue value = QJSValue::NullValue;
if(variant != nullptr) {
value = variant->toQJSValue();
}
_jsValue.setProperty(arrayIndex, value);
}
extern "C" {
Q_DECL_EXPORT void net_js_value_destroy(NetJSValueContainer* jsValueContainer) {
delete jsValueContainer;
}
Q_DECL_EXPORT uchar net_js_value_isCallable(NetJSValueContainer* jsValueContainer) {
auto result = jsValueContainer->jsValue->isCallable();
if (result) {
return 1;
} else {
return 0;
}
}
Q_DECL_EXPORT uchar net_js_value_isArray(NetJSValueContainer* jsValueContainer) {
auto result = jsValueContainer->jsValue->isArray();
if (result) {
return 1;
} else {
return 0;
}
}
Q_DECL_EXPORT NetVariantContainer* net_js_value_call(NetJSValueContainer* jsValueContainer, NetVariantListContainer* parametersContainer) {
QSharedPointer<NetVariantList> parameters;
if(parametersContainer != nullptr) {
parameters = parametersContainer->list;
}
QSharedPointer<NetVariant> result = jsValueContainer->jsValue->call(parameters);
if(result != nullptr) {
return new NetVariantContainer{result};
}
return nullptr;
}
Q_DECL_EXPORT NetVariantContainer* net_js_value_getProperty(NetJSValueContainer* jsValueContainer, LPWSTR propertyName) {
QSharedPointer<NetVariant> result = jsValueContainer->jsValue->getProperty(QString::fromUtf16(static_cast<const char16_t*>(propertyName)));
if(result == nullptr) {
return nullptr;
}
return new NetVariantContainer{result};
}
Q_DECL_EXPORT NetVariantContainer* net_js_value_getItemAtIndex(NetJSValueContainer* jsValueContainer, quint32 arrayIndex) {
QSharedPointer<NetVariant> result = jsValueContainer->jsValue->getItemAtIndex(arrayIndex);
if(result == nullptr) {
return nullptr;
}
return new NetVariantContainer{result};
}
Q_DECL_EXPORT void net_js_value_setProperty(NetJSValueContainer* jsValueContainer, LPWSTR propertyName, NetVariantContainer* valueContainer) {
QSharedPointer<NetVariant> value;
if(valueContainer != nullptr) {
value = valueContainer->variant;
}
jsValueContainer->jsValue->setProperty(QString::fromUtf16(static_cast<const char16_t*>(propertyName)), value);
}
Q_DECL_EXPORT void net_js_value_setItemAtIndex(NetJSValueContainer* jsValueContainer, quint32 arrayIndex, NetVariantContainer* valueContainer) {
QSharedPointer<NetVariant> value;
if(valueContainer != nullptr) {
value = valueContainer->variant;
}
jsValueContainer->jsValue->setItemAtIndex(arrayIndex, value);
}
}

View file

@ -1,32 +0,0 @@
#ifndef NETJSVALUE_H
#define NETJSVALUE_H
#include <QmlNet.h>
#include <QJSValue>
#include <QSharedPointer>
class NetVariant;
class NetVariantList;
class NetJSValue
{
public:
NetJSValue(QJSValue jsValue);
~NetJSValue();
QJSValue getJsValue();
bool isCallable() const;
bool isArray() const;
QSharedPointer<NetVariant> call(const QSharedPointer<NetVariantList>& parameters);
QSharedPointer<NetVariant> getProperty(const QString& propertyName);
QSharedPointer<NetVariant> getItemAtIndex(quint32 arrayIndex);
void setProperty(const QString& propertyName, const QSharedPointer<NetVariant>& variant);
void setItemAtIndex(quint32 arrayIndex, const QSharedPointer<NetVariant>& variant);
private:
QJSValue _jsValue;
};
struct NetJSValueContainer {
QSharedPointer<NetJSValue> jsValue;
};
#endif // NETJSVALUE_H

View file

@ -1,76 +0,0 @@
#include <QmlNet/qml/NetListModel.h>
#include <QmlNet/types/NetReference.h>
#include <QmlNet/types/NetTypeArrayFacade.h>
#include <QmlNet/qml/NetVariant.h>
#include <QDebug>
NetListModel::NetListModel(
QObject* parent,
QSharedPointer<NetTypeArrayFacade> facade,
QSharedPointer<NetReference> reference) :
QAbstractListModel(parent),
_facade(std::move(facade)),
_reference(std::move(reference))
{
}
NetListModel* NetListModel::fromReference(const QSharedPointer<NetReference>& reference)
{
QSharedPointer<NetTypeArrayFacade> facade = reference->getTypeInfo()->getArrayFacade();
if(facade == nullptr) {
return nullptr;
}
return new NetListModel(nullptr, facade, reference);
}
QVariant NetListModel::data(const QModelIndex &index, int role) const
{
if(role != 0) {
qWarning() << "invalid role id:" << role;
return QVariant();
}
int length = static_cast<int>(_facade->getLength(_reference));
if (index.row() < 0 || index.row() >= length)
return QVariant();
QSharedPointer<NetVariant> result = _facade->getIndexed(_reference, static_cast<uint>(index.row()));
if(result == nullptr) {
return QVariant();
}
return result->toQVariant();
}
int NetListModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return static_cast<int>(_facade->getLength(_reference));
}
QHash<int,QByteArray> NetListModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[0] = "modelData";
return roles;
}
QVariant NetListModel::at(int index)
{
if(index < 0) {
return QVariant();
}
int length = static_cast<int>(_facade->getLength(_reference));
if(index >= length) {
return QVariant();
}
QSharedPointer<NetVariant> result = _facade->getIndexed(_reference, static_cast<uint>(index));
if(result == nullptr) {
return QVariant();
}
return result->toQVariant();
}
int NetListModel::length()
{
return static_cast<int>(_facade->getLength(_reference));
}

View file

@ -1,30 +0,0 @@
#ifndef NETLISTMODEL_H
#define NETLISTMODEL_H
#include <QAbstractListModel>
#include <QSharedPointer>
class NetTypeArrayFacade;
class NetReference;
class NetListModel : public QAbstractListModel
{
Q_OBJECT
public:
NetListModel(QObject* parent, QSharedPointer<NetTypeArrayFacade> facade, QSharedPointer<NetReference> reference);
static NetListModel* fromReference(const QSharedPointer<NetReference>& reference);
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
QHash<int,QByteArray> roleNames() const;
Q_INVOKABLE QVariant at(int index);
Q_INVOKABLE int length();
private:
QSharedPointer<NetTypeArrayFacade> _facade;
QSharedPointer<NetReference> _reference;
};
#endif // NETLISTMODEL_H

View file

@ -1,344 +0,0 @@
#include <QmlNet/qml/NetQObject.h>
#include <QmlNet/qml/NetQObjectSignalConnection.h>
#include <QmlNet/qml/NetQObjectArg.h>
#include <QmlNet/types/NetDelegate.h>
#include <QmlNet/types/Callbacks.h>
#include <QMetaMethod>
#include <QDebug>
NetQObject::NetQObject(QObject* qObject, bool ownsObject) :
_qObject(qObject),
_ownsObject(ownsObject)
{
}
NetQObject::~NetQObject()
{
if(_ownsObject) {
_qObject->deleteLater();
}
}
QObject* NetQObject::getQObject()
{
return _qObject;
}
QSharedPointer<NetVariant> NetQObject::getProperty(QString propertyName, bool* wasSuccess)
{
QSharedPointer<NetVariant> netVariant;
QByteArray propertyNameLocal = propertyName.toLocal8Bit();
if(_qObject->metaObject()->indexOfProperty(propertyNameLocal.data()) == -1) {
if(wasSuccess) {
*wasSuccess = false;
}
return nullptr;
}
QVariant result = _qObject->property(propertyNameLocal.data());
if(!result.isNull()) {
netVariant = QSharedPointer<NetVariant>(new NetVariant());
NetVariant::fromQVariant(&result, netVariant);
}
if(wasSuccess) {
*wasSuccess = true;
}
return netVariant;
}
void NetQObject::setProperty(QString propertyName, QSharedPointer<NetVariant> value, bool* wasSuccess)
{
bool result;
if(value == nullptr) {
result = _qObject->setProperty(propertyName.toLocal8Bit().data(), QVariant());
} else {
result = _qObject->setProperty(propertyName.toLocal8Bit().data(), value->toQVariant());
}
if(wasSuccess) {
*wasSuccess = result;
}
}
QSharedPointer<NetVariant> NetQObject::invokeMethod(QString methodName, QSharedPointer<NetVariantList> parameters, bool* wasSuccess)
{
int parameterCount = 0;
if(parameters != nullptr) {
parameterCount = parameters->count();
}
// Find the best method
int methodIndex = -1;
QMetaMethod method;
for(int x = 0; x < _qObject->metaObject()->methodCount(); x++) {
method = _qObject->metaObject()->method(x);
if(method.methodType() == QMetaMethod::Slot || method.methodType() == QMetaMethod::Method) {
if(methodName.compare(method.name()) == 0) {
// make sure number of parameters match
if(method.parameterCount() == parameterCount) {
methodIndex = x;
break;
}
}
}
}
if(methodIndex == -1) {
if(wasSuccess) {
*wasSuccess = false;
}
return nullptr;
}
if(parameterCount > 10) {
qWarning() << "Attempting to invoke a method with too many parameters: current: " << parameters->count() << " expected: <=10";
if(wasSuccess) {
*wasSuccess = false;
}
return nullptr;
}
NetQObjectArg returnValue(method.returnType());
NetQObjectArg val0;
NetQObjectArg val1;
NetQObjectArg val2;
NetQObjectArg val3;
NetQObjectArg val4;
NetQObjectArg val5;
NetQObjectArg val6;
NetQObjectArg val7;
NetQObjectArg val8;
NetQObjectArg val9;
if(parameterCount >= 1) {
val0 = NetQObjectArg(method.parameterType(0), parameters->get(0));
}
if(parameterCount >= 2) {
val0 = NetQObjectArg(method.parameterType(1), parameters->get(1));
}
if(parameterCount >= 3) {
val0 = NetQObjectArg(method.parameterType(2), parameters->get(2));
}
if(parameterCount >= 4) {
val0 = NetQObjectArg(method.parameterType(3), parameters->get(3));
}
if(parameterCount >= 5) {
val0 = NetQObjectArg(method.parameterType(4), parameters->get(4));
}
if(parameterCount >= 6) {
val0 = NetQObjectArg(method.parameterType(5), parameters->get(5));
}
if(parameterCount >= 7) {
val0 = NetQObjectArg(method.parameterType(6), parameters->get(6));
}
if(parameterCount >= 8) {
val0 = NetQObjectArg(method.parameterType(7), parameters->get(7));
}
if(parameterCount >= 9) {
val0 = NetQObjectArg(method.parameterType(8), parameters->get(8));
}
if(parameterCount >= 10) {
val0 = NetQObjectArg(method.parameterType(9), parameters->get(9));
}
if(!method.invoke(_qObject,
Qt::DirectConnection,
returnValue.genericReturnArguemnet(),
val0.genericArgument(),
val1.genericArgument(),
val2.genericArgument(),
val3.genericArgument(),
val4.genericArgument(),
val5.genericArgument(),
val6.genericArgument(),
val7.genericArgument(),
val8.genericArgument(),
val9.genericArgument())) {
if(wasSuccess) {
*wasSuccess = false;
}
return nullptr;
}
if(wasSuccess) {
*wasSuccess = true;
}
returnValue.unpack();
return returnValue.getNetVariant();
}
QSharedPointer<NetQObjectSignalConnection> NetQObject::attachSignal(QString signalName, QSharedPointer<NetReference> delegate, bool* wasSucessful)
{
int signalMethodIndex = -1;
QMetaMethod signalMethod;
for(int x = 0; x <_qObject->metaObject()->methodCount(); x++) {
signalMethod = _qObject->metaObject()->method(x);
if(signalMethod.methodType() == QMetaMethod::Signal) {
if(signalName.compare(signalMethod.name()) == 0) {
signalMethodIndex = x;
break;
}
}
}
// If signal not found, dump the registered signals for debugging.
if(signalMethodIndex < 0) {
if(wasSucessful) {
*wasSucessful = false;
}
return nullptr;
}
QSharedPointer<NetQObjectSignalConnection> signalConnection = QSharedPointer<NetQObjectSignalConnection>(new NetQObjectSignalConnection(delegate, _qObject));
QMetaObject::Connection connection = QObject::connect(_qObject,
signalMethod,
signalConnection.data(),
signalConnection->getSignalHandler());
if(!connection) {
if(wasSucessful) {
*wasSucessful = false;
}
return nullptr;
}
if(wasSucessful) {
*wasSucessful = true;
}
return signalConnection;
}
QSharedPointer<NetQObjectSignalConnection> NetQObject::attachNotifySignal(QString propertyName, QSharedPointer<NetReference> delegate, bool* wasSuccessful)
{
int propertyIndex = _qObject->metaObject()->indexOfProperty(propertyName.toLocal8Bit().data());
if(propertyIndex == -1) {
if(wasSuccessful) {
*wasSuccessful = false;
}
return nullptr;
}
QMetaProperty property = _qObject->metaObject()->property(propertyIndex);
if(property.notifySignalIndex() == -1) {
if(wasSuccessful) {
*wasSuccessful = false;
}
return nullptr;
}
QSharedPointer<NetQObjectSignalConnection> signalConnection = QSharedPointer<NetQObjectSignalConnection>(new NetQObjectSignalConnection(delegate, _qObject));
QMetaObject::Connection connection = QObject::connect(_qObject,
property.notifySignal(),
signalConnection.data(),
signalConnection->getSignalHandler());
if(!connection) {
if(wasSuccessful) {
*wasSuccessful = false;
}
return nullptr;
}
if(wasSuccessful) {
*wasSuccessful = true;
}
return signalConnection;
}
extern "C" {
Q_DECL_EXPORT void net_qobject_destroy(NetQObjectContainer* qObjectContainer)
{
delete qObjectContainer;
}
Q_DECL_EXPORT NetVariantContainer* net_qobject_getProperty(NetQObjectContainer* qObjectContainer, LPWCSTR propertyName, uchar* result)
{
bool wasSuccesful = false;
auto value = qObjectContainer->qObject->getProperty(QString::fromUtf16(propertyName), &wasSuccesful);
if(wasSuccesful) {
*result = 1;
} else {
*result = 0;
}
if(value == nullptr) {
return nullptr;
}
return new NetVariantContainer{ value };
}
Q_DECL_EXPORT void net_qobject_setProperty(NetQObjectContainer* qObjectContainer, LPWCSTR propertyName, NetVariantContainer* netVariantContainer, uchar* result)
{
bool wasSuccesful = false;
if(netVariantContainer == nullptr) {
qObjectContainer->qObject->setProperty(QString::fromUtf16(propertyName), nullptr, &wasSuccesful);
} else {
qObjectContainer->qObject->setProperty(QString::fromUtf16(propertyName), netVariantContainer->variant, &wasSuccesful);
}
if(wasSuccesful) {
*result = 1;
} else {
*result = 0;
}
}
Q_DECL_EXPORT NetVariantContainer* net_qobject_invokeMethod(NetQObjectContainer* qObjectContainer, LPWCSTR methodName, NetVariantListContainer* parametersContainer, uchar* result)
{
QSharedPointer<NetVariantList> parameters = nullptr;
if(parametersContainer != nullptr) {
parameters = parametersContainer->list;
}
bool wasSuccesful = false;
auto value = qObjectContainer->qObject->invokeMethod(QString::fromUtf16(methodName), parameters, &wasSuccesful);
if(wasSuccesful) {
*result = 1;
} else {
*result = 0;
}
if(value == nullptr) {
return nullptr;
}
return new NetVariantContainer { value };
}
Q_DECL_EXPORT NetQObjectSignalConnectionContainer* net_qobject_attachSignal(NetQObjectContainer* qObjectContainer, LPWCSTR signalName, NetReferenceContainer* delegate, uchar* result)
{
bool wasSuccesful = false;
auto signalConnection = qObjectContainer->qObject->attachSignal(QString::fromUtf16(signalName), delegate->instance, &wasSuccesful);
if(wasSuccesful) {
*result = 1;
} else {
*result = 0;
}
if(signalConnection == nullptr) {
return nullptr;
}
return new NetQObjectSignalConnectionContainer { signalConnection };
}
Q_DECL_EXPORT NetQObjectSignalConnectionContainer* net_qobject_attachNotifySignal(NetQObjectContainer* qObjectContainer, LPWCSTR propertyName, NetReferenceContainer* delegate, uchar* result)
{
bool wasSuccesful = false;
auto signalConnection = qObjectContainer->qObject->attachNotifySignal(QString::fromUtf16(propertyName), delegate->instance, &wasSuccesful);
if(wasSuccesful) {
*result = 1;
} else {
*result = 0;
}
if(signalConnection == nullptr) {
return nullptr;
}
return new NetQObjectSignalConnectionContainer { signalConnection };
}
Q_DECL_EXPORT void net_qobject_signal_handler_destroy(NetQObjectSignalConnectionContainer* signalContainer)
{
delete signalContainer;
}
}

View file

@ -1,32 +0,0 @@
#ifndef NETQOBJECT_H
#define NETQOBJECT_H
#include <QmlNet.h>
#include <QSharedPointer>
class NetVariant;
class NetVariantList;
class NetQObjectSignalConnection;
class NetReference;
class NetQObject
{
public:
NetQObject(QObject* qObject, bool ownsObject = false);
~NetQObject();
QObject* getQObject();
QSharedPointer<NetVariant> getProperty(QString propertyName, bool* wasSuccess);
void setProperty(QString propertyName, QSharedPointer<NetVariant> value, bool* wasSuccess);
QSharedPointer<NetVariant> invokeMethod(QString methodName, QSharedPointer<NetVariantList> parameters, bool* wasSuccess);
QSharedPointer<NetQObjectSignalConnection> attachSignal(QString signalName, QSharedPointer<NetReference> delegate, bool* wasSuccess);
QSharedPointer<NetQObjectSignalConnection> attachNotifySignal(QString propertyName, QSharedPointer<NetReference> delegate, bool* wasSuccess);
private:
QObject* _qObject;
bool _ownsObject;
};
struct NetQObjectContainer {
QSharedPointer<NetQObject> qObject;
};
#endif // NETQOBJECT_H

View file

@ -1,139 +0,0 @@
#include <QmlNet/qml/NetQObjectArg.h>
#include <QmlNet/qml/NetVariant.h>
#include <QDebug>
NetQObjectArg::NetQObjectArg() :
_metaTypeId(QMetaType::Void),
_data(nullptr)
{
pack();
}
NetQObjectArg::NetQObjectArg(const int metaTypeId, QSharedPointer<NetVariant> netVariant) :
_metaTypeId(metaTypeId),
_data(nullptr),
_netVariant(netVariant)
{
pack();
}
NetQObjectArg::~NetQObjectArg()
{
}
QGenericArgument NetQObjectArg::genericArgument()
{
if(_metaTypeId == QMetaType::Void) {
return QGenericArgument();
}
if(_metaTypeId == QMetaType::QVariant) {
return QGenericArgument("QVariant", &_variant);
}
return QGenericArgument(_variant.typeName(), _variant.data());
}
QGenericReturnArgument NetQObjectArg::genericReturnArguemnet()
{
if(_metaTypeId == QMetaType::Void) {
return QGenericReturnArgument();
}
if(_metaTypeId == QMetaType::QVariant) {
return QGenericReturnArgument("QVariant", &_variant);
}
return QGenericReturnArgument(_variant.typeName(), _variant.data());
}
QSharedPointer<NetVariant> NetQObjectArg::getNetVariant()
{
return _netVariant;
}
void NetQObjectArg::pack()
{
if(_netVariant == nullptr) {
switch(_metaTypeId) {
case QMetaType::Void:
break;
case QMetaType::QVariant:
_variant = QVariant();
break;
default:
_variant = QVariant(_metaTypeId, nullptr);
break;
}
return;
}
switch(_metaTypeId) {
case QMetaType::Void:
break;
case QMetaType::QVariant:
_variant = _netVariant->toQVariant();
break;
case QMetaType::Bool:
_variant = QVariant::fromValue(_netVariant->getBool());
break;
case QMetaType::QChar:
_variant = QVariant::fromValue(_netVariant->getChar());
break;
case qMetaTypeId<qint32>():
_variant = QVariant::fromValue(_netVariant->getInt());
break;
case qMetaTypeId<quint32>():
_variant = QVariant::fromValue(_netVariant->getUInt());
break;
case qMetaTypeId<qint64>():
_variant = QVariant::fromValue(_netVariant->getLong());
break;
case qMetaTypeId<quint64>():
_variant = QVariant::fromValue(_netVariant->getULong());
break;
case QMetaType::Long:
_variant = QVariant::fromValue<long>(static_cast<long>(_netVariant->getLong()));
break;
case QMetaType::ULong:
_variant = QVariant::fromValue<ulong>(static_cast<ulong>(_netVariant->getULong()));
break;
case QMetaType::Float:
_variant = QVariant::fromValue(_netVariant->getFloat());
break;
case QMetaType::Double:
_variant = QVariant::fromValue(_netVariant->getDouble());
break;
case QMetaType::QString:
_variant = QVariant::fromValue(_netVariant->getString());
break;
case QMetaType::QDateTime:
_variant = QVariant::fromValue(_netVariant->getDateTime());
break;
case QMetaType::QObjectStar:
switch(_netVariant->getVariantType()) {
case NetVariantTypeEnum_Invalid:
_variant = QVariant::fromValue<QObject*>(nullptr);
break;
case NetVariantTypeEnum_Object:
case NetVariantTypeEnum_QObject:
_variant = _netVariant->toQVariant();
break;
default:
qWarning() << "Unabled to convert " << _netVariant->getVariantType() << " to QObject*";
break;
}
break;
default:
qWarning() << "Unsupported type: " << QMetaType::typeName(_metaTypeId);
_variant = QVariant(_metaTypeId, nullptr);
break;
}
}
void NetQObjectArg::unpack()
{
if(_metaTypeId == QMetaType::Void) {
return;
}
if(_netVariant == nullptr) {
_netVariant = QSharedPointer<NetVariant>(new NetVariant());
}
NetVariant::fromQVariant(&_variant, _netVariant);
}

View file

@ -1,28 +0,0 @@
#ifndef NETQOBJECTARG_H
#define NETQOBJECTARG_H
#include <QMetaMethod>
#include <QSharedPointer>
class NetVariant;
class NetQObjectArg
{
public:
NetQObjectArg();
NetQObjectArg(int metaTypeId, QSharedPointer<NetVariant> netVariant = nullptr);
~NetQObjectArg();
QGenericArgument genericArgument();
QGenericReturnArgument genericReturnArguemnet();
QSharedPointer<NetVariant> getNetVariant();
void pack();
void unpack();
private:
int _metaTypeId;
void* _data;
int test;
QVariant _variant;
QSharedPointer<NetVariant> _netVariant;
};
#endif // NETQOBJECTARG_H

View file

@ -1,65 +0,0 @@
#include <QmlNet/qml/NetQObjectSignalConnection.h>
#include <QmlNet/qml/NetVariant.h>
#include <QmlNet/qml/NetVariantList.h>
#include <QmlNet/types/Callbacks.h>
#include <QMetaMethod>
NetQObjectSignalConnectionBase::NetQObjectSignalConnectionBase()
{
}
NetQObjectSignalConnectionBase::~NetQObjectSignalConnectionBase()
{
}
QMetaMethod NetQObjectSignalConnectionBase::getSignalHandler()
{
return metaObject()->method(metaObject()->methodOffset());
}
void NetQObjectSignalConnectionBase::signalRaised()
{
// Dummy, handled in NetQObjectSignalConnection::qt_metacall()
}
NetQObjectSignalConnection::NetQObjectSignalConnection(QSharedPointer<NetReference> delegate,
QObject* qObject)
: _delegate(delegate),
_qObject(qObject)
{
}
NetQObjectSignalConnection::~NetQObjectSignalConnection()
{
}
int NetQObjectSignalConnection::qt_metacall(QMetaObject::Call c, int id, void** a)
{
if(c == QMetaObject::InvokeMetaMethod) {
int offset = this->metaObject()->methodOffset();
if(id < offset) {
return QObject::qt_metacall(c, id, a);
}
if(this->metaObject()->indexOfSlot("signalRaised()") == id) {
QMetaMethod signal = _qObject->metaObject()->method(senderSignalIndex());
// Convert signal args to QVariantList
QSharedPointer<NetVariantList> netParameters = QSharedPointer<NetVariantList>(new NetVariantList());
for (int i = 0; i < signal.parameterCount(); ++i) {
QVariant arg = QVariant(signal.parameterType(i), a[i+1]);
netParameters->add(NetVariant::fromQVariant(&arg));
}
QmlNet::invokeDelegate(_delegate, netParameters);
return -1;
}
}
return id;
}

View file

@ -1,35 +0,0 @@
#ifndef NETQOBJECTSIGNALCONNECTION_H
#define NETQOBJECTSIGNALCONNECTION_H
#include <QObject>
#include <QSharedPointer>
class NetReference;
class NetQObjectSignalConnectionBase : public QObject
{
Q_OBJECT
public:
NetQObjectSignalConnectionBase();
~NetQObjectSignalConnectionBase();
QMetaMethod getSignalHandler();
public slots:
void signalRaised();
};
class NetQObjectSignalConnection : public NetQObjectSignalConnectionBase
{
public:
NetQObjectSignalConnection(QSharedPointer<NetReference> delegate, QObject* qObject);
~NetQObjectSignalConnection() override;
int qt_metacall(QMetaObject::Call c, int id, void** a) override;
private:
QSharedPointer<NetReference> _delegate;
QObject* _qObject;
};
struct NetQObjectSignalConnectionContainer {
QSharedPointer<NetQObjectSignalConnection> signalConnection;
};
#endif // NETQOBJECTSIGNALCONNECTION_H

View file

@ -1,189 +0,0 @@
#include <QmlNet/qml/NetTestHelper.h>
#include <QQmlComponent>
#include <QDebug>
TestQObject::TestQObject()
: QObject(nullptr),
_writeOnly(0),
_readAndWrite(0),
_propWithSignal(0)
{
}
TestQObject::~TestQObject()
{
}
int TestQObject::getReadOnly()
{
return 3;
}
void TestQObject::setWriteOnly(int value)
{
_writeOnly = value;
}
int TestQObject::getReadAndWrite()
{
return _readAndWrite;
}
void TestQObject::setReadAndWrite(int value)
{
_readAndWrite = value;
}
int TestQObject::getPropWithSignal()
{
return _propWithSignal;
}
void TestQObject::setPropWithSignal(int value)
{
if(value == _propWithSignal) {
return;
}
_propWithSignal = value;
emit propWithSignalChanged(value);
}
QVariant TestQObject::getVariantProperty()
{
return _variantValue;
}
void TestQObject::setVariantProperty(QVariant value)
{
_variantValue = value;
}
void TestQObject::testSlot()
{
emit testSignal();
}
void TestQObject::testSlotWithArg(int arg)
{
emit testSignalWithArg(arg);
}
QVariant TestQObject::testVariantReturn()
{
return getVariantProperty();
}
bool TestQObject::testSlotBool(bool value)
{
emit testSignalBool(value);
return value;
}
QChar TestQObject::testSlotChar(QChar value)
{
emit testSignalChar(value);
return value;
}
int TestQObject::testSlotInt(int value)
{
emit testSignalInt(value);
return value;
}
uint TestQObject::testSlotUInt(uint value)
{
emit testSignalUInt(value);
return value;
}
long TestQObject::testSlotLong(long value)
{
emit testSignalLong(value);
return value;
}
ulong TestQObject::testSlotULong(ulong value)
{
emit testSignalULong(value);
return value;
}
float TestQObject::testSlotFloat(float value)
{
emit testSignalFloat(value);
return value;
}
double TestQObject::testSlotDouble(double value)
{
emit testSignalDouble(value);
return value;
}
QString TestQObject::testSlotString(QString value)
{
emit testSignalString(value);
return value;
}
QDateTime TestQObject::testSlotDateTime(QDateTime value)
{
emit testSignalDateTime(value);
return value;
}
QObject* TestQObject::testSlotQObject(QObject* value)
{
emit testSignalQObject(value);
return value;
}
qint32 TestQObject::testSlotQInt32(qint32 value)
{
emit testSignalQInt32(value);
return value;
}
quint32 TestQObject::testSlotQUInt32(quint32 value)
{
emit testSignalQUInt32(value);
return value;
}
qint64 TestQObject::testSlotQInt64(qint64 value)
{
emit testSignalQInt64(value);
return value;
}
quint64 TestQObject::testSlotQUInt64(quint64 value)
{
emit testSignalQUInt64(value);
return value;
}
extern "C" {
Q_DECL_EXPORT void net_test_helper_runQml(QQmlApplicationEngineContainer* qmlEngineContainer, LPWSTR qml) {
QQmlComponent component(qmlEngineContainer->qmlEngine);
QString qmlString = QString::fromUtf16(static_cast<const char16_t*>(qml));
component.setData(qmlString.toUtf8(), QUrl());
QObject *object = component.create();
if(object == nullptr) {
qWarning() << "Couldn't create qml object.";
return;
}
QSharedPointer<TestQObject> testQObject = QSharedPointer<TestQObject>(new TestQObject());
object->setProperty("testQObject", QVariant::fromValue(testQObject.data()));
QMetaObject::invokeMethod(object, "runTest");
delete object;
}
}

View file

@ -1,74 +0,0 @@
#ifndef NETTESTHELPER_H
#define NETTESTHELPER_H
#include <QmlNet.h>
#include <QmlNet/qml/QQmlApplicationEngine.h>
#include <QDateTime>
class TestQObject : public QObject
{
Q_OBJECT
Q_PROPERTY(int readOnly READ getReadOnly)
Q_PROPERTY(int writeOnly WRITE setWriteOnly)
Q_PROPERTY(int readAndWrite READ getReadAndWrite WRITE setReadAndWrite)
Q_PROPERTY(int propWithSignal READ getPropWithSignal WRITE setPropWithSignal NOTIFY propWithSignalChanged)
Q_PROPERTY(QVariant variantProperty READ getVariantProperty WRITE setVariantProperty)
public:
TestQObject();
~TestQObject();
int getReadOnly();
void setWriteOnly(int value);
int getReadAndWrite();
void setReadAndWrite(int value);
int getPropWithSignal();
void setPropWithSignal(int value);
QVariant getVariantProperty();
void setVariantProperty(QVariant value);
signals:
void propWithSignalChanged(int value);
void testSignal();
void testSignalWithArg(int arg);
void testSignalBool(bool value);
void testSignalChar(QChar value);
void testSignalInt(int value);
void testSignalUInt(uint value);
void testSignalLong(long value);
void testSignalULong(ulong value);
void testSignalFloat(float value);
void testSignalDouble(double value);
void testSignalString(QString value);
void testSignalDateTime(QDateTime value);
void testSignalQObject(QObject* qObject);
void testSignalQInt32(qint32 value);
void testSignalQUInt32(quint32 value);
void testSignalQInt64(qint64 value);
void testSignalQUInt64(quint64 value);
public slots:
void testSlot();
void testSlotWithArg(int arg);
QVariant testVariantReturn();
bool testSlotBool(bool value);
QChar testSlotChar(QChar value);
int testSlotInt(int value);
uint testSlotUInt(uint value);
long testSlotLong(long value);
ulong testSlotULong(ulong value);
float testSlotFloat(float value);
double testSlotDouble(double value);
QString testSlotString(QString value);
QDateTime testSlotDateTime(QDateTime value);
QObject* testSlotQObject(QObject* value);
qint32 testSlotQInt32(qint32 value);
quint32 testSlotQUInt32(quint32 value);
qint64 testSlotQInt64(qint64 value);
quint64 testSlotQUInt64(quint64 value);
private:
int _writeOnly;
int _readAndWrite;
int _propWithSignal;
QVariant _variantValue;
};
#endif // NETTESTHELPER_H

View file

@ -1,165 +0,0 @@
#include <QQmlEngine>
#include <QmlNet/qml/NetValue.h>
#include <QmlNet/qml/NetValueMetaObject.h>
#include <QmlNet/types/NetSignalInfo.h>
#include <QmlNet/types/NetTypeManager.h>
#include <QmlNet/types/Callbacks.h>
#include <QDebug>
#include <utility>
NetValue::~NetValue()
{
auto objectId = instance->getObjectId();
auto hit = objectIdNetValuesMap.find(objectId);
if(hit != objectIdNetValuesMap.end()) {
NetValueCollection* collection = hit.value();
collection->netValues.removeOne(this);
if(collection->netValues.length() == 0) {
objectIdNetValuesMap.remove(objectId);
delete collection;
}
}
if(this->instance->getTypeInfo()->hasObjectDestroyed()){
QmlNet::callObjectDestroyed(instance);
}
#ifdef QMLNET_TRACE
qDebug("netvalue: destroyed: for: %s", qPrintable(instance->displayName()));
#endif
instance = nullptr;
}
QSharedPointer<NetReference> NetValue::getNetReference()
{
return instance;
}
bool NetValue::activateSignal(const QString& signalName, const QSharedPointer<NetVariantList>& arguments)
{
int signalMethodIndex = -1;
for(int x = 0; valueMeta->methodCount(); x++) {
QByteArray methodName = valueMeta->method(x).name();
if(signalName.compare(methodName) == 0) {
signalMethodIndex = x;
break;
}
}
// If signal not found, dump the registered signals for debugging.
if(signalMethodIndex < 0) {
qDebug() << "Signal not found:" << signalName;
qDebug() << "Current signals:";
for (int i = 0; i < metaObject()->methodCount(); i++) {
QMetaMethod method = metaObject()->method(i);
if (method.methodType() == QMetaMethod::Signal) {
qDebug().nospace() << "\t" << method.methodSignature();
}
}
return false;
}
// Build the types needed to activate the signal
QList<QSharedPointer<QVariant>> variantArgs;
std::vector<void*> voidArgs;
voidArgs.push_back(nullptr); // For the return type, which is nothing for signals.
if(arguments != nullptr) {
for(int x = 0 ; x < arguments->count(); x++) {
QSharedPointer<QVariant> variant(new QVariant(arguments->get(x)->toQVariant()));
variantArgs.append(variant);
voidArgs.push_back(static_cast<void*>(variant.data()));
}
}
void** argsPointer = nullptr;
if(!voidArgs.empty()) {
argsPointer = &voidArgs[0];
}
// Activate the signal!
NetValueMetaObject::activate(this, signalMethodIndex, argsPointer);
return true;
}
NetValue* NetValue::forInstance(const QSharedPointer<NetReference>& instance)
{
NetValue* result = new NetValue(instance, nullptr);
QQmlEngine::setObjectOwnership(result, QQmlEngine::JavaScriptOwnership);
return result;
}
QList<NetValue*> NetValue::getAllLiveInstances(const QSharedPointer<NetReference>& instance)
{
auto objectId = instance->getObjectId();
NetValueCollection* collection = nullptr;
auto hit = objectIdNetValuesMap.find(objectId);
if(hit != objectIdNetValuesMap.end()) {
collection = hit.value();
return collection->netValues;
}
return QList<NetValue*>();
}
void NetValue::classBegin()
{
}
void NetValue::componentComplete()
{
if(this->instance->getTypeInfo()->hasComponentCompleted()){
QmlNet::callComponentCompleted(instance);
}
}
NetValue::NetValue(const QSharedPointer<NetReference>& instance, QObject *parent)
: instance(instance)
{
#ifdef QMLNET_TRACE
qDebug("netvalue: created: for: %s", qPrintable(instance->displayName()));
#endif
valueMeta = new NetValueMetaObject(this, instance);
setParent(parent);
auto objectId = instance->getObjectId();
NetValueCollection* collection = nullptr;
auto hit = objectIdNetValuesMap.find(objectId);
if(hit != objectIdNetValuesMap.end()) {
collection = hit.value();
} else {
collection = new NetValueCollection();
objectIdNetValuesMap.insert(objectId, collection);
}
collection->netValues.append(this);
QList<QSharedPointer<NetTypeInfo>> types;
auto type = instance->getTypeInfo();
while(type != nullptr) {
types.insert(0, type);
type = NetTypeManager::getBaseType(type);
}
for(QSharedPointer<NetTypeInfo> type : types) {
for(int index = 0; index <= type->getSignalCount() - 1; index++) {
QSharedPointer<NetSignalInfo> signalInfo = type->getSignal(index);
QString signalSig = signalInfo->getSignature();
QString slotSig = signalInfo->getSlotSignature();
int signalIndex = valueMeta->indexOfSignal(signalSig.toLatin1().data());
int slotIndex = valueMeta->indexOfSlot(slotSig.toLatin1().data());
QMetaMethod signalMethod = valueMeta->method(signalIndex);
QMetaMethod slotMethod = valueMeta->method(slotIndex);
QObject::connect(this, signalMethod,
this, slotMethod);
}
}
}
QMap<uint64_t, NetValue::NetValueCollection*> NetValue::objectIdNetValuesMap = QMap<uint64_t, NetValue::NetValueCollection*>();

View file

@ -1,53 +0,0 @@
#ifndef NETVALUE_H
#define NETVALUE_H
#include <map>
#include <QmlNet.h>
#include <QmlNet/types/NetReference.h>
#include <QmlNet/qml/NetVariantList.h>
#include <QObject>
#include <QSharedPointer>
#include <QQmlParserStatus>
class NetValueMetaObject;
struct NetValueInterface
{
virtual ~NetValueInterface() {}
virtual QSharedPointer<NetReference> getNetReference() = 0;
};
Q_DECLARE_INTERFACE(NetValueInterface, "netcoreqml.NetValueInterface")
class NetValue : public QObject, NetValueInterface, public QQmlParserStatus
{
Q_OBJECT
Q_INTERFACES(NetValueInterface)
Q_INTERFACES(QQmlParserStatus)
public:
virtual ~NetValue();
QSharedPointer<NetReference> getNetReference();
bool activateSignal(const QString& signalName, const QSharedPointer<NetVariantList>& arguments);
static NetValue* forInstance(const QSharedPointer<NetReference>& instance);
static QList<NetValue*> getAllLiveInstances(const QSharedPointer<NetReference>& instance);
virtual void classBegin() override;
virtual void componentComplete() override;
protected:
NetValue(const QSharedPointer<NetReference>& instance, QObject *parent);
QSharedPointer<NetReference> instance;
private:
NetValueMetaObject* valueMeta;
struct NetValueCollection {
QList<NetValue*> netValues;
};
static QMap<uint64_t, NetValueCollection*> objectIdNetValuesMap;
};
#endif // NETVALUE_H

View file

@ -1,285 +0,0 @@
#include <QmlNet/qml/NetValueMetaObject.h>
#include <QmlNet/qml/NetValueMetaObjectPacker.h>
#include <QmlNet/types/NetTypeInfo.h>
#include <QmlNet/types/NetMethodInfo.h>
#include <QmlNet/types/NetPropertyInfo.h>
#include <QmlNet/types/NetSignalInfo.h>
#include <QmlNet/types/Callbacks.h>
#include <QmlNet/types/NetTypeManager.h>
#include <QQmlEngine>
#include <QDebug>
#include <private/qmetaobjectbuilder_p.h>
QMetaObject *metaObjectFor(const QSharedPointer<NetTypeInfo>& typeInfo)
{
if (typeInfo->metaObject) {
return typeInfo->metaObject;
}
typeInfo->ensureLoaded();
QMetaObjectBuilder mob;
mob.setClassName(typeInfo->getClassName().toLatin1());
mob.setFlags(QMetaObjectBuilder::DynamicMetaObject);
QString baseType = typeInfo->getBaseType();
if(baseType.isNull() || baseType.isEmpty()) {
mob.setSuperClass(&QObject::staticMetaObject);
} else {
auto baseTypeInfo = NetTypeManager::getTypeInfo(baseType);
mob.setSuperClass(metaObjectFor(baseTypeInfo));
}
// register all the signals for the type
for(int index = 0; index <= typeInfo->getSignalCount() - 1; index++)
{
QSharedPointer<NetSignalInfo> signalInfo = typeInfo->getSignal(index);
QString signature = signalInfo->getSignature();
mob.addSignal(QMetaObject::normalizedSignature(signature.toLocal8Bit().constData()));
}
// NOTE: It is important to register properties after the signals (before methods)
// because of the assumptions we make about getting the "notifySignal" by index.
for(int index = 0; index <= typeInfo->getPropertyCount() - 1; index++)
{
QSharedPointer<NetPropertyInfo> propertyInfo = typeInfo->getProperty(index);
QSharedPointer<NetTypeInfo> propertyType = propertyInfo->getReturnType();
QString propertyName = propertyInfo->getPropertyName();
if(propertyName.at(0).isUpper()) {
propertyName.replace(0,1, propertyName.at(0).toLower());
}
QMetaPropertyBuilder propb = mob.addProperty(propertyName.toLatin1(),
NetMetaValueQmlType(propertyType->getPrefVariantType()),
index);
QSharedPointer<NetSignalInfo> notifySignal = propertyInfo->getNotifySignal();
if(notifySignal != nullptr) {
// The signal was previously registered, find the index.
for(int signalIndex = 0; signalIndex <= typeInfo->getSignalCount() - 1; signalIndex++)
{
if(typeInfo->getSignal(signalIndex) == notifySignal) {
QMetaMethodBuilder notifySignalBuilder = mob.method(signalIndex);
propb.setNotifySignal(notifySignalBuilder);
break;
}
}
}
propb.setWritable(propertyInfo->canWrite());
propb.setReadable(propertyInfo->canRead());
}
for(int index = 0; index <= typeInfo->getLocalMethodCount() - 1; index++)
{
QSharedPointer<NetMethodInfo> methodInfo = typeInfo->getLocalMethodInfo(index);
QSharedPointer<NetTypeInfo> returnType = methodInfo->getReturnType();
QString signature = methodInfo->getSignature();
if(returnType != nullptr) {
mob.addMethod(QMetaObject::normalizedSignature(signature.toLocal8Bit().constData()),
NetMetaValueQmlType(returnType->getPrefVariantType()));
} else {
mob.addMethod(QMetaObject::normalizedSignature(signature.toLocal8Bit().constData()));
}
}
// For every signal that was added, add an associated slot
// so that we can auto-hook the slot to each signal so that
// we can raise .NET-attached delegates.
for(int index = 0; index <= typeInfo->getSignalCount() - 1; index++)
{
QSharedPointer<NetSignalInfo> signalInfo = typeInfo->getSignal(index);
QString signature = signalInfo->getSlotSignature();
mob.addSlot(signature.toLatin1().data());
}
QMetaObject *mo = mob.toMetaObject();
typeInfo->metaObject = mo;
return mo;
}
NetValueMetaObject::NetValueMetaObject(QObject *value,
const QSharedPointer<NetReference>& instance) :
value(value),
instance(instance)
{
*static_cast<QMetaObject *>(this) = *metaObjectFor(instance->getTypeInfo());
QObjectPrivate *objPriv = QObjectPrivate::get(value);
objPriv->metaObject = this;
}
int NetValueMetaObject::metaCall(QMetaObject::Call c, int idx, void **a)
{
#ifdef QMLNET_TRACE
switch(c) {
case ReadProperty:
{
auto prop = property(idx);
qDebug() << this->className() << ": reading property: " << idx << ": " << prop.name();
}
break;
case WriteProperty:
{
auto prop = property(idx);
qDebug() << this->className() << ": writing property: " << idx << ": " << prop.name();
}
break;
case InvokeMetaMethod:
{
auto meth = method(idx);
qDebug() << this->className() << ": invoking method: " << idx << ": " << meth.name();
}
break;
default:
break; // Unhandled.
}
#endif
return metaCallRecursive(c, idx, idx, a, instance->getTypeInfo());
}
int NetValueMetaObject::metaCallRecursive(QMetaObject::Call c, int originalIdx, int idx, void **a, QSharedPointer<NetTypeInfo> typeInfo)
{
switch(c) {
case ReadProperty:
{
int offset = propertyOffset();
if (idx < offset) {
auto baseType = NetTypeManager::getBaseType(typeInfo);
if(baseType != nullptr) {
return metaCallRecursive(c, originalIdx, idx + baseType->getPropertyCount(), a, baseType);
}
return value->qt_metacall(c, idx, a);
}
QSharedPointer<NetPropertyInfo> propertyInfo = typeInfo->getProperty(idx - offset);
QSharedPointer<NetTypeInfo> propertyType = propertyInfo->getReturnType();
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
#ifdef QMLNET_TRACE
qDebug("begin: read: %s.%s", qPrintable(instance->displayName()),
qPrintable(propertyInfo->getPropertyName()));
#endif
QmlNet::readProperty(propertyInfo, instance, nullptr, result);
#ifdef QMLNET_TRACE
qDebug("end: read: %s.%s value: %s", qPrintable(instance->displayName()),
qPrintable(propertyInfo->getPropertyName()),
qPrintable(result->getDisplayValue()));
#endif
NetMetaValuePack(propertyType->getPrefVariantType(), result, a[0]);
}
break;
case WriteProperty:
{
int offset = propertyOffset();
if (idx < offset) {
auto baseType = NetTypeManager::getBaseType(typeInfo);
if(baseType != nullptr) {
return metaCallRecursive(c, originalIdx, idx + baseType->getPropertyCount(), a, baseType);
}
return value->qt_metacall(c, idx, a);
}
QSharedPointer<NetPropertyInfo> propertyInfo = typeInfo->getProperty(idx - offset);
QSharedPointer<NetTypeInfo> propertyType = propertyInfo->getReturnType();
QSharedPointer<NetVariant> newValue = QSharedPointer<NetVariant>(new NetVariant());
NetMetaValueUnpack(propertyType->getPrefVariantType(), newValue, a[0]);
QmlNet::writeProperty(propertyInfo, instance, nullptr, newValue);
}
break;
case InvokeMetaMethod:
{
int offset = methodOffset();
if (idx < offset) {
auto baseType = NetTypeManager::getBaseType(typeInfo);
if(baseType != nullptr) {
return metaCallRecursive(c, originalIdx, idx + ((baseType->getSignalCount() * 2) + baseType->getLocalMethodCount()), a, baseType);
}
return value->qt_metacall(c, idx, a);
}
idx -= offset;
if(idx < typeInfo->getSignalCount()) {
// This is a signal call, activate it!
activate(value, originalIdx, a);
return -1;
}
idx -= typeInfo->getSignalCount();
if(idx < typeInfo->getLocalMethodCount()) {
// This is a method call!
QSharedPointer<NetMethodInfo> methodInfo = typeInfo->getLocalMethodInfo(idx);
QSharedPointer<NetVariantList> parameters = QSharedPointer<NetVariantList>(new NetVariantList());
for(int index = 0; index <= methodInfo->getParameterCount() - 1; index++)
{
QSharedPointer<NetMethodInfoArguement> parameter = methodInfo->getParameter(index);
QSharedPointer<NetTypeInfo> parameterType = parameter->getType();
QSharedPointer<NetVariant> netVariant = QSharedPointer<NetVariant>(new NetVariant());
NetMetaValueUnpack(parameterType->getPrefVariantType(), netVariant, a[index + 1]);
parameters->add(netVariant);
}
QSharedPointer<NetVariant> result;
QSharedPointer<NetTypeInfo> returnType = methodInfo->getReturnType();
if(returnType != nullptr) {
result = QSharedPointer<NetVariant>(new NetVariant());
}
QmlNet::invokeNetMethod(methodInfo, instance, parameters, result);
#ifdef QMLNET_TRACE
if(result != nullptr) {
qDebug("end: method: %s.%s(%s) result: %s", qPrintable(instance->displayName()),
qPrintable(methodInfo->getMethodName()),
qPrintable(parameters->debugDisplay()),
qPrintable(result->getDisplayValue()));
} else {
qDebug("end: method: %s.%s(%s)", qPrintable(instance->displayName()),
qPrintable(methodInfo->getMethodName()),
qPrintable(parameters->debugDisplay()));
}
#endif
if(result != nullptr) {
NetMetaValuePack(returnType->getPrefVariantType(), result, a[0]);
}
return -1;
}
idx -= typeInfo->getLocalMethodCount();
{
// This is a slot invocation, likely the built-in handlers that are used
// to trigger NET delegates for any signals.
QSharedPointer<NetSignalInfo> signalInfo = typeInfo->getSignal(idx);
QSharedPointer<NetVariantList> parameters;
if(signalInfo->getParameterCount() > 0) {
parameters = QSharedPointer<NetVariantList>(new NetVariantList());
for(int index = 0; index <= signalInfo->getParameterCount() - 1; index++)
{
NetVariantTypeEnum parameterType = signalInfo->getParameter(index);
QSharedPointer<NetVariant> netVariant = QSharedPointer<NetVariant>(new NetVariant());
NetMetaValueUnpack(parameterType, netVariant, a[index + 1]);
parameters->add(netVariant);
}
}
QmlNet::raiseNetSignals(instance, signalInfo->getName(), parameters);
}
}
break;
default:
break; // Unhandled.
}
return -1;
}

View file

@ -1,26 +0,0 @@
#ifndef NETVALUEMETAOBJECT_H
#define NETVALUEMETAOBJECT_H
#include <QmlNet.h>
#include <QmlNet/qml/NetVariant.h>
#include <QmlNet/qml/NetValue.h>
#include <private/qobject_p.h>
QMetaObject *metaObjectFor(const QSharedPointer<NetTypeInfo>& typeInfo);
class NetValueMetaObject : public QAbstractDynamicMetaObject
{
public:
NetValueMetaObject(QObject* value, const QSharedPointer<NetReference>& instance);
protected:
int metaCall(QMetaObject::Call c, int id, void **a);
private:
int metaCallRecursive(QMetaObject::Call c, int originalIdx, int idx, void **a, QSharedPointer<NetTypeInfo> typeInfo);
QObject *value;
QSharedPointer<NetReference> instance;
};
#endif // NETVALUEMETAOBJECT_H

View file

@ -1,229 +0,0 @@
#include <QmlNet/qml/NetValueMetaObjectPacker.h>
#include <QmlNet/qml/NetVariant.h>
#include <QmlNet/qml/NetValue.h>
#include <QmlNet/qml/NetJsValue.h>
#include <QmlNet/qml/NetQObject.h>
#include <QDebug>
const char* NetValueTypePacker::getQmlType()
{
return "QVariant";
}
void NetValueTypePacker::pack(const QSharedPointer<NetVariant>& source, void* destination)
{
QVariant* destinationVariant = static_cast<QVariant*>(destination);
switch(source->getVariantType()) {
case NetVariantTypeEnum_Invalid:
destinationVariant->setValue(QVariant::fromValue(nullptr));
break;
case NetVariantTypeEnum_Bool:
destinationVariant->setValue(source->getBool());
break;
case NetVariantTypeEnum_Char:
destinationVariant->setValue(source->getChar());
break;
case NetVariantTypeEnum_Int:
destinationVariant->setValue(source->getInt());
break;
case NetVariantTypeEnum_UInt:
destinationVariant->setValue(source->getUInt());
break;
case NetVariantTypeEnum_Long:
destinationVariant->setValue(source->getLong());
break;
case NetVariantTypeEnum_ULong:
destinationVariant->setValue(source->getULong());
break;
case NetVariantTypeEnum_Float:
destinationVariant->setValue(source->getFloat());
break;
case NetVariantTypeEnum_Double:
destinationVariant->setValue(source->getDouble());
break;
case NetVariantTypeEnum_String:
destinationVariant->setValue(source->getString());
break;
case NetVariantTypeEnum_DateTime:
destinationVariant->setValue(source->getDateTime());
break;
case NetVariantTypeEnum_Object:
{
QSharedPointer<NetReference> newInstance = source->getNetReference();
NetValue* netValue = NetValue::forInstance(newInstance);
destinationVariant->setValue(netValue);
break;
}
case NetVariantTypeEnum_JSValue:
destinationVariant->setValue(source->getJsValue()->getJsValue());
break;
case NetVariantTypeEnum_QObject:
destinationVariant->setValue(source->getQObject()->getQObject());
break;
}
}
void NetValueTypePacker::unpack(const QSharedPointer<NetVariant>& destination, void* source, NetVariantTypeEnum prefType)
{
QVariant* sourceVariant = static_cast<QVariant*>(source);
if(sourceVariant->isNull()) {
destination->clear();
return;
}
switch(prefType) {
case NetVariantTypeEnum_Invalid:
destination->clear();
return;
case NetVariantTypeEnum_Bool:
destination->setBool(sourceVariant->toBool());
return;
case NetVariantTypeEnum_Char:
{
const QString& v = sourceVariant->toString();
if(v.length() == 1) {
destination->setChar(v.at(0));
} else {
qDebug() << "Can't set string" << v << "to char.";
destination->setChar(QChar::Null);
}
return;
}
case NetVariantTypeEnum_Int:
destination->setInt(sourceVariant->value<qint32>());
return;
case NetVariantTypeEnum_UInt:
destination->setUInt(sourceVariant->value<quint32>());
return;
case NetVariantTypeEnum_Long:
destination->setLong(sourceVariant->value<qint64>());
return;
case NetVariantTypeEnum_ULong:
destination->setULong(sourceVariant->value<quint64>());
return;
case NetVariantTypeEnum_Float:
destination->setFloat(sourceVariant->toFloat());
return;
case NetVariantTypeEnum_Double:
destination->setDouble(sourceVariant->toDouble());
return;
case NetVariantTypeEnum_String:
destination->setString(sourceVariant->toString());
return;
case NetVariantTypeEnum_DateTime:
destination->setDateTime(sourceVariant->toDateTime());
return;
case NetVariantTypeEnum_Object:
{
if(sourceVariant->userType() == QMetaType::QObjectStar) {
QObject* value = sourceVariant->value<QObject*>();
NetValueInterface* netValue = qobject_cast<NetValueInterface*>(value);
if(netValue) {
destination->setNetReference(netValue->getNetReference());
} else {
QSharedPointer<NetQObject> netQObject(new NetQObject(value));
destination->setQObject(netQObject);
}
return;
}
break;
}
case NetVariantTypeEnum_JSValue:
{
if(sourceVariant->userType() == qMetaTypeId<QJSValue>()) {
QSharedPointer<NetJSValue> netJsValue(new NetJSValue(sourceVariant->value<QJSValue>()));
destination->setJsValue(netJsValue);
return;
}
// TODO: Try to convert other types to JS Value.
break;
}
case NetVariantTypeEnum_QObject:
{
if(sourceVariant->userType() == QMetaType::QObjectStar) {
QSharedPointer<NetQObject> netQObject(new NetQObject(sourceVariant->value<QObject*>()));
}
}
}
NetVariant::fromQVariant(sourceVariant, destination);
}
namespace
{
class StringValueTypePacker : public NetValueTypePacker
{
public:
const char* getQmlType() override
{
return "QString";
}
void pack(const QSharedPointer<NetVariant>& source, void* destination) override
{
Q_ASSERT(source->getVariantType() == NetVariantTypeEnum_String || source->getVariantType() == NetVariantTypeEnum_Invalid);
QString* destinationString = static_cast<QString*>(destination);
switch(source->getVariantType()){
case NetVariantTypeEnum_Invalid:
destinationString->clear();
break;
case NetVariantTypeEnum_String:
*destinationString = source->getString();
break;
default:
qWarning() << "Attempting to set a variant id" << source->getVariantType() << "to a QString";
break;
}
}
void unpack(const QSharedPointer<NetVariant>& destination, void* source, NetVariantTypeEnum prefType) override
{
Q_ASSERT(prefType == NetVariantTypeEnum_String);
QString* sourceString = static_cast<QString*>(source);
destination->setString(sourceString);
}
};
}
NetValueMetaObjectPacker::NetValueMetaObjectPacker()
{
NetValueTypePacker* variantPacker = new NetValueTypePacker();
StringValueTypePacker* stringPacker = new StringValueTypePacker();
//This is might not be pretty, but it does allow the compiler generate a warning if a value is missing.
for (int typeInt = NetVariantTypeEnum_Invalid; typeInt <= NetVariantTypeEnum_JSValue; ++typeInt)
{
NetVariantTypeEnum type = NetVariantTypeEnum(typeInt);
switch(type) {
case NetVariantTypeEnum_Invalid:
case NetVariantTypeEnum_Bool:
case NetVariantTypeEnum_Char:
case NetVariantTypeEnum_Int:
case NetVariantTypeEnum_UInt:
case NetVariantTypeEnum_Long:
case NetVariantTypeEnum_ULong:
case NetVariantTypeEnum_Float:
case NetVariantTypeEnum_Double:
case NetVariantTypeEnum_DateTime:
case NetVariantTypeEnum_Object:
case NetVariantTypeEnum_JSValue:
case NetVariantTypeEnum_QObject:
packers[type] = variantPacker;
break;
case NetVariantTypeEnum_String:
packers[type] = stringPacker;
break;
}
}
}
NetValueMetaObjectPacker* NetValueMetaObjectPacker::getInstance()
{
static NetValueMetaObjectPacker packer;
return &packer;
}
NetValueTypePacker* NetValueMetaObjectPacker::getPacker(NetVariantTypeEnum variantType)
{
Q_ASSERT(packers.contains(variantType));
return packers[variantType];
}

View file

@ -1,37 +0,0 @@
#ifndef NETVALUEMETAOBJECTPACKER_H
#define NETVALUEMETAOBJECTPACKER_H
#include <QmlNet.h>
#include <QSharedPointer>
#include <QMap>
class NetVariant;
class NetValueTypePacker
{
public:
NetValueTypePacker() {}
virtual ~NetValueTypePacker() {}
virtual const char* getQmlType();
virtual void pack(const QSharedPointer<NetVariant>& source, void* destination);
virtual void unpack(const QSharedPointer<NetVariant>& destination, void* source, NetVariantTypeEnum prefType);
};
#define NetMetaValuePack(type, source, destination) \
NetValueMetaObjectPacker::getInstance()->getPacker(type)->pack(source, destination)
#define NetMetaValueUnpack(type, destination, source) \
NetValueMetaObjectPacker::getInstance()->getPacker(type)->unpack(destination, source, type)
#define NetMetaValueQmlType(type) \
NetValueMetaObjectPacker::getInstance()->getPacker(type)->getQmlType()
class NetValueMetaObjectPacker
{
public:
NetValueMetaObjectPacker();
static NetValueMetaObjectPacker* getInstance();
NetValueTypePacker* getPacker(NetVariantTypeEnum variantType);
private:
QMap<NetVariantTypeEnum, NetValueTypePacker*> packers;
};
#endif // NETVALUEMETAOBJECTPACKER_H

View file

@ -1 +0,0 @@
#include <QmlNet/qml/NetValueType.h>

View file

@ -1,40 +0,0 @@
#ifndef NETVALUETYPE_H
#define NETVALUETYPE_H
#include <QmlNet.h>
#include <QmlNet/qml/NetValue.h>
#include <QmlNet/qml/NetValueMetaObject.h>
#include <QmlNet/types/Callbacks.h>
#include <QQmlEngine>
template <int N>
class NetValueType : public NetValue
{
public:
NetValueType()
: NetValue(QmlNet::instantiateType(typeInfo), nullptr) {}
static void init(QSharedPointer<NetTypeInfo> info)
{
typeInfo = info;
static_cast<QMetaObject &>(staticMetaObject) = *metaObjectFor(typeInfo);
}
static QObject *build(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
return new NetValueType<N>();
}
static QSharedPointer<NetTypeInfo> typeInfo;
static QMetaObject staticMetaObject;
};
template <int N>
QSharedPointer<NetTypeInfo> NetValueType<N>::typeInfo = nullptr;
template <int N>
QMetaObject NetValueType<N>::staticMetaObject = QMetaObject();
#endif // NETVALUETYPE_H

View file

@ -1,623 +0,0 @@
#include <QmlNet/types/NetReference.h>
#include <QmlNet/qml/NetVariant.h>
#include <QmlNet/qml/NetValue.h>
#include <QmlNet/qml/NetJsValue.h>
#include <QmlNet/qml/NetQObject.h>
#include <QmlNetUtilities.h>
#include <QDateTime>
#include <QDebug>
#include <QJSEngine>
#include <QmlNet/qml/QQmlApplicationEngine.h>
namespace
{
struct NetReferenceQmlContainer
{
QSharedPointer<NetReference> netReference;
};
struct NetJsValueQmlContainer
{
QSharedPointer<NetJSValue> jsValue;
};
struct NetQObjectQmlContainer
{
QSharedPointer<NetQObject> netQObject;
};
}
Q_DECLARE_METATYPE(NetReferenceQmlContainer)
Q_DECLARE_METATYPE(NetJsValueQmlContainer)
Q_DECLARE_METATYPE(NetQObjectQmlContainer)
namespace
{
const int NetReferenceQmlContainerTypeId = qMetaTypeId<NetReferenceQmlContainer>();
const int NetJsValueQmlContainerTypeId = qMetaTypeId<NetJsValueQmlContainer>();
const int NetQObjectQmlContainerTypeId = qMetaTypeId<NetQObjectQmlContainer>();
}
NetVariant::NetVariant() = default;
NetVariant::~NetVariant()
{
clearNetReference();
}
NetVariantTypeEnum NetVariant::getVariantType() const
{
const int type = variant.userType();
switch(type) {
case QMetaType::UnknownType:
return NetVariantTypeEnum_Invalid;
case QMetaType::Bool:
return NetVariantTypeEnum_Bool;
case QMetaType::QChar:
return NetVariantTypeEnum_Char;
case qMetaTypeId<qint32>():
return NetVariantTypeEnum_Int;
case qMetaTypeId<quint32>():
return NetVariantTypeEnum_UInt;
case qMetaTypeId<qint64>():
return NetVariantTypeEnum_Long;
case qMetaTypeId<quint64>():
return NetVariantTypeEnum_ULong;
case QMetaType::Float:
return NetVariantTypeEnum_Float;
case QMetaType::Double:
return NetVariantTypeEnum_Double;
case QMetaType::QString:
return NetVariantTypeEnum_String;
case QMetaType::QDateTime:
return NetVariantTypeEnum_DateTime;
default:
if(type == NetReferenceQmlContainerTypeId) {
return NetVariantTypeEnum_Object;
}
else if(type == NetJsValueQmlContainerTypeId) {
return NetVariantTypeEnum_JSValue;
}
else if(type == NetQObjectQmlContainerTypeId) {
return NetVariantTypeEnum_QObject;
}
else {
qWarning() << "Unknown type for NetVariant: " << variant.typeName();
return NetVariantTypeEnum_Invalid;
}
}
}
void NetVariant::setNetReference(QSharedPointer<NetReference> netReference)
{
clearNetReference();
variant.setValue(NetReferenceQmlContainer{ std::move(netReference) });
}
QSharedPointer<NetReference> NetVariant::getNetReference() const
{
return getValue<NetReferenceQmlContainer>().netReference;
}
void NetVariant::setBool(bool value)
{
setValue(value);
}
bool NetVariant::getBool() const
{
return getValue<bool>();
}
void NetVariant::setChar(QChar value)
{
setValue(value);
}
QChar NetVariant::getChar() const
{
return getValue<QChar>();
}
void NetVariant::setInt(qint32 value)
{
setValue(value);
}
qint32 NetVariant::getInt() const
{
return getValue<qint32>();
}
void NetVariant::setUInt(quint32 value)
{
setValue(value);
}
quint32 NetVariant::getUInt() const
{
return getValue<quint32>();
}
void NetVariant::setLong(qint64 value)
{
setValue(value);
}
qint64 NetVariant::getLong() const
{
return getValue<qint64>();
}
void NetVariant::setULong(quint64 value)
{
setValue(value);
}
quint64 NetVariant::getULong() const
{
return getValue<quint64>();
}
void NetVariant::setFloat(float value)
{
setValue(value);
}
float NetVariant::getFloat() const
{
return getValue<float>();
}
void NetVariant::setDouble(double value)
{
setValue(value);
}
double NetVariant::getDouble() const
{
return getValue<double>();
}
void NetVariant::setString(const QString* value)
{
setValuePtr(value);
}
void NetVariant::setString(const QString& value)
{
setValue(value);
}
QString NetVariant::getString() const
{
if(variant.userType() != QMetaType::QString) {
qDebug() << "Variant is not a string";
return QString();
}
return variant.toString();
}
void NetVariant::setDateTime(const QDateTime& value)
{
setValue(value);
}
QDateTime NetVariant::getDateTime() const
{
return getValue<QDateTime>();
}
void NetVariant::setJsValue(QSharedPointer<NetJSValue> jsValue)
{
setValue(NetJsValueQmlContainer{ std::move(jsValue) });
}
QSharedPointer<NetJSValue> NetVariant::getJsValue() const
{
return getValue<NetJsValueQmlContainer>().jsValue;
}
void NetVariant::setQObject(QSharedPointer<NetQObject> netQObject)
{
setValue(NetQObjectQmlContainer{ std::move(netQObject) });
}
QSharedPointer<NetQObject> NetVariant::getQObject() const
{
return getValue<NetQObjectQmlContainer>().netQObject;
}
void NetVariant::clear()
{
clearNetReference();
variant.clear();
}
QSharedPointer<NetVariant> NetVariant::fromQJSValue(const QJSValue& qJsValue)
{
QSharedPointer<NetVariant> result;
if(qJsValue.isNull() || qJsValue.isUndefined()) {
// Nothing!
}
else if(qJsValue.isQObject()) {
QObject* qObject = qJsValue.toQObject();
NetValueInterface* netValue = qobject_cast<NetValueInterface*>(qObject);
if(!netValue) {
qWarning() << "Return type must be a JS type/object, or a .NET object.";
} else {
result = QSharedPointer<NetVariant>(new NetVariant());
result->setNetReference(netValue->getNetReference());
}
}
else if(qJsValue.isObject()) {
result = QSharedPointer<NetVariant>(new NetVariant());
result->setJsValue(QSharedPointer<NetJSValue>(new NetJSValue(qJsValue)));
} else {
result = QSharedPointer<NetVariant>(new NetVariant());
QVariant variant = qJsValue.toVariant();
result->variant = variant;
}
return result;
}
QJSValue NetVariant::toQJSValue() const
{
switch(getVariantType()) {
case NetVariantTypeEnum_Object: {
NetValue* netValue = NetValue::forInstance(getNetReference());
return sharedQmlEngine()->newQObject(netValue);
}
case NetVariantTypeEnum_JSValue: {
return getJsValue()->getJsValue();
}
default: {
return sharedQmlEngine()->toScriptValue<QVariant>(toQVariant());
}
}
}
void NetVariant::fromQVariant(const QVariant* variant, const QSharedPointer<NetVariant>& destination)
{
const int type = variant->userType();
switch(type) {
case QMetaType::UnknownType:
destination->clear();
break;
case QMetaType::Bool:
case QMetaType::QChar:
case qMetaTypeId<qint32>():
case qMetaTypeId<quint32>():
case qMetaTypeId<qint64>():
case qMetaTypeId<quint64>():
case QMetaType::Float:
case QMetaType::Double:
case QMetaType::QString:
case QMetaType::QDateTime:
destination->setValueVariant(*variant);
break;
case QMetaType::ULong:
destination->setULong(variant->value<quint64>());
break;
case QMetaType::Long:
destination->setLong(variant->value<qint64>());
break;
case QMetaType::QObjectStar: {
QObject* value = variant->value<QObject*>();
if(value == nullptr) {
destination->clear();
return;
}
NetValueInterface* netValue = qobject_cast<NetValueInterface*>(value);
if(netValue) {
destination->setNetReference(netValue->getNetReference());
} else {
destination->setQObject(QSharedPointer<NetQObject>(new NetQObject(value)));
}
break;
}
default:
if(type == qMetaTypeId<QJSValue>()) {
// TODO: Either serialize this type to a string, to be deserialized in .NET, or
// pass raw value to .NET to be dynamically invoked (using dynamic).
// See qtdeclarative\src\plugins\qmltooling\qmldbg_debugger\qqmlenginedebugservice.cpp:184
// for serialization methods.
QSharedPointer<NetJSValue> netJsValue(new NetJSValue(variant->value<QJSValue>()));
destination->setJsValue(netJsValue);
break;
}
qDebug() << "Unsupported variant type: " << variant->type() << variant->typeName();
break;
}
}
QSharedPointer<NetVariant> NetVariant::fromQVariant(const QVariant* variant)
{
QSharedPointer<NetVariant> result(new NetVariant());
fromQVariant(variant, result);
return result;
}
QVariant NetVariant::toQVariant() const
{
switch(getVariantType()) {
case NetVariantTypeEnum_JSValue:
return getJsValue()->getJsValue().toVariant();
case NetVariantTypeEnum_Object:
return QVariant::fromValue<QObject*>(NetValue::forInstance(getNetReference()));
case NetVariantTypeEnum_QObject:
return QVariant::fromValue<QObject*>(this->getQObject()->getQObject());
default:
return variant;
}
}
QString NetVariant::getDisplayValue() const
{
switch(getVariantType()) {
case NetVariantTypeEnum_JSValue:
return getJsValue()->getJsValue().toString();
case NetVariantTypeEnum_Object:
return getNetReference()->displayName();
default:
return variant.toString();
}
}
void NetVariant::clearNetReference()
{
if(variant.canConvert<NetReferenceQmlContainer>()) {
variant.value<NetReferenceQmlContainer>().netReference.clear();
variant.clear();
}
else if(variant.canConvert<NetJsValueQmlContainer>()) {
variant.value<NetJsValueQmlContainer>().jsValue.clear();
variant.clear();
}
else if(variant.canConvert<NetQObjectQmlContainer>()) {
variant.value<NetQObjectQmlContainer>().netQObject.clear();
variant.clear();
}
}
template<typename T>
void NetVariant::setValue(const T& value)
{
clearNetReference();
variant.setValue(value);
}
void NetVariant::setValueVariant(const QVariant& value)
{
Q_ASSERT(value.userType() != QMetaType::QObjectStar);
Q_ASSERT(value.userType() != qMetaTypeId<QJSValue>());
Q_ASSERT(value.userType() < QMetaType::User);
clearNetReference();
variant = value;
}
template<typename T>
void NetVariant::setValuePtr(const T* value)
{
if(value) {
setValue(*value);
} else {
clear();
}
}
template<typename T>
T NetVariant::getValue() const
{
if(!variant.canConvert(qMetaTypeId<T>())) {
qDebug() << "Can't convert value" << variant << "from" << variant.typeName() << "to" << QMetaType::typeName(qMetaTypeId<T>());
}
return variant.value<T>();
}
extern "C" {
struct Q_DECL_EXPORT DateTimeContainer {
uchar isNull;
int month;
int day;
int year;
int hour;
int minute;
int second;
int msec;
int offsetSeconds;
};
Q_DECL_EXPORT NetVariantContainer* net_variant_create() {
NetVariantContainer* result = new NetVariantContainer();
result->variant = QSharedPointer<NetVariant>(new NetVariant());
return result;
}
Q_DECL_EXPORT void net_variant_destroy(NetVariantContainer* container) {
delete container;
}
Q_DECL_EXPORT NetVariantTypeEnum net_variant_getVariantType(NetVariantContainer* container) {
return container->variant->getVariantType();
}
Q_DECL_EXPORT void net_variant_setNetReference(NetVariantContainer* container, NetReferenceContainer* instanceContainer) {
if(instanceContainer == nullptr) {
container->variant->setNetReference(nullptr);
} else {
container->variant->setNetReference(instanceContainer->instance);
}
}
Q_DECL_EXPORT NetReferenceContainer* net_variant_getNetReference(NetVariantContainer* container) {
QSharedPointer<NetReference> instance = container->variant->getNetReference();
if(instance == nullptr) {
return nullptr;
}
NetReferenceContainer* result = new NetReferenceContainer();
result->instance = instance;
return result;
}
Q_DECL_EXPORT void net_variant_setBool(NetVariantContainer* container, uchar value) {
container->variant->setBool(value == 1 ? true : false);
}
Q_DECL_EXPORT uchar net_variant_getBool(NetVariantContainer* container) {
if(container->variant->getBool()) {
return 1;
} else {
return 0;
}
}
Q_DECL_EXPORT void net_variant_setChar(NetVariantContainer* container, quint16 value) {
container->variant->setChar(value);
}
Q_DECL_EXPORT quint16 net_variant_getChar(NetVariantContainer* container) {
return quint16(container->variant->getChar().unicode());
}
Q_DECL_EXPORT void net_variant_setInt(NetVariantContainer* container, qint32 value) {
container->variant->setInt(value);
}
Q_DECL_EXPORT qint32 net_variant_getInt(NetVariantContainer* container) {
return container->variant->getInt();
}
Q_DECL_EXPORT void net_variant_setUInt(NetVariantContainer* container, quint32 value) {
container->variant->setUInt(value);
}
Q_DECL_EXPORT quint32 net_variant_getUInt(NetVariantContainer* container) {
return container->variant->getUInt();
}
Q_DECL_EXPORT void net_variant_setLong(NetVariantContainer* container, qint64 value) {
container->variant->setLong(value);
}
Q_DECL_EXPORT qint64 net_variant_getLong(NetVariantContainer* container) {
return container->variant->getLong();
}
Q_DECL_EXPORT void net_variant_setULong(NetVariantContainer* container, quint64 value) {
container->variant->setULong(value);
}
Q_DECL_EXPORT quint64 net_variant_getULong(NetVariantContainer* container) {
return container->variant->getULong();
}
Q_DECL_EXPORT void net_variant_setFloat(NetVariantContainer* container, float value) {
container->variant->setFloat(value);
}
Q_DECL_EXPORT float net_variant_getFloat(NetVariantContainer* container) {
return container->variant->getFloat();
}
Q_DECL_EXPORT void net_variant_setDouble(NetVariantContainer* container, double value) {
container->variant->setDouble(value);
}
Q_DECL_EXPORT double net_variant_getDouble(NetVariantContainer* container) {
return container->variant->getDouble();
}
Q_DECL_EXPORT void net_variant_setString(NetVariantContainer* container, LPWSTR value) {
if(value == nullptr) {
container->variant->setString(nullptr);
} else {
container->variant->setString(QString::fromUtf16(static_cast<const char16_t*>(value)));
}
}
Q_DECL_EXPORT QmlNetStringContainer* net_variant_getString(NetVariantContainer* container) {
const QString& string = container->variant->getString();
if(string.isNull()) {
return nullptr;
}
return createString(string);
}
Q_DECL_EXPORT void net_variant_setDateTime(NetVariantContainer* container, const DateTimeContainer* value) {
if(value == nullptr || value->isNull) {
container->variant->setDateTime(QDateTime());
} else {
container->variant->setDateTime(QDateTime(QDate(value->year, value->month, value->day),
QTime(value->hour, value->minute, value->second, value->msec),
Qt::OffsetFromUTC, value->offsetSeconds));
}
}
Q_DECL_EXPORT void net_variant_getDateTime(NetVariantContainer* container, DateTimeContainer* value) {
const QDateTime& dt = container->variant->getDateTime();
if(dt.isNull()) {
value->isNull = 1;
return;
}
if(!dt.isValid()) {
qWarning() << "QDateTime is invalid";
value->isNull = 1;
return;
}
value->isNull = 0;
const QDate& date = dt.date();
const QTime& time = dt.time();
value->year = date.year();
value->month = date.month();
value->day = date.day();
value->hour = time.hour();
value->minute = time.minute();
value->second = time.second();
value->msec = time.msec();
value->offsetSeconds = dt.offsetFromUtc();
}
Q_DECL_EXPORT void net_variant_setJsValue(NetVariantContainer* container, NetJSValueContainer* jsValueContainer) {
if(jsValueContainer == nullptr) {
container->variant->setJsValue(nullptr);
} else {
container->variant->setJsValue(jsValueContainer->jsValue);
}
}
Q_DECL_EXPORT NetJSValueContainer* net_variant_getJsValue(NetVariantContainer* container) {
const QSharedPointer<NetJSValue>& instance = container->variant->getJsValue();
if(instance == nullptr) {
return nullptr;
}
NetJSValueContainer* result = new NetJSValueContainer();
result->jsValue = instance;
return result;
}
Q_DECL_EXPORT void net_variant_setQObject(NetVariantContainer* container, NetQObjectContainer* qObjectContainer) {
if(qObjectContainer == nullptr) {
container->variant->setQObject(nullptr);
} else {
container->variant->setQObject(qObjectContainer->qObject);
}
}
Q_DECL_EXPORT NetQObjectContainer* net_variant_getQObject(NetVariantContainer* container) {
const QSharedPointer<NetQObject>& instance = container->variant->getQObject();
if(instance == nullptr) {
return nullptr;
}
NetQObjectContainer* result = new NetQObjectContainer();
result->qObject = instance;
return result;
}
Q_DECL_EXPORT void net_variant_clear(NetVariantContainer* container) {
container->variant->clear();
}
}

View file

@ -1,74 +0,0 @@
#ifndef NETVARIANT_H
#define NETVARIANT_H
#include <QmlNet.h>
#include <QSharedPointer>
#include <QVariant>
#include <QDateTime>
#include <QJSValue>
class NetJSValue;
class NetQObject;
class NetReference;
class NetVariant
{
public:
NetVariant();
~NetVariant();
NetVariantTypeEnum getVariantType() const;
void setNetReference(QSharedPointer<NetReference> netReference);
QSharedPointer<NetReference> getNetReference() const;
void setBool(bool value);
bool getBool() const;
void setChar(QChar value);
QChar getChar() const;
void setInt(qint32 value);
qint32 getInt() const;
void setUInt(quint32 value);
quint32 getUInt() const;
void setLong(qint64 value);
qint64 getLong() const;
void setULong(quint64 value);
quint64 getULong() const;
void setFloat(float value);
float getFloat() const;
void setDouble(double value);
double getDouble() const;
void setString(const QString* value);
void setString(const QString& value);
QString getString() const;
void setDateTime(const QDateTime& value);
QDateTime getDateTime() const;
void setJsValue(QSharedPointer<NetJSValue> jsValue);
QSharedPointer<NetJSValue> getJsValue() const;
void setQObject(QSharedPointer<NetQObject> netQObject);
QSharedPointer<NetQObject> getQObject() const;
void clear();
static QSharedPointer<NetVariant> fromQJSValue(const QJSValue& qJsValue);
QJSValue toQJSValue() const;
static void fromQVariant(const QVariant* variant, const QSharedPointer<NetVariant>& destination);
static QSharedPointer<NetVariant> fromQVariant(const QVariant* variant);
QVariant toQVariant() const;
QString getDisplayValue() const;
private:
void clearNetReference();
template<typename T>
void setValue(const T& value);
void setValueVariant(const QVariant& value);
template<typename T>
void setValuePtr(const T* value);
template<typename T>
T getValue() const;
QVariant variant;
};
struct NetVariantContainer {
QSharedPointer<NetVariant> variant;
};
#endif // NETVARIANT_H

View file

@ -1,77 +0,0 @@
#include <QmlNet/qml/NetVariantList.h>
NetVariantList::NetVariantList() = default;
NetVariantList::~NetVariantList() = default;
int NetVariantList::count() {
return variants.size();
}
void NetVariantList::add(const QSharedPointer<NetVariant>& variant) {
variants.append(variant);
}
QSharedPointer<NetVariant> NetVariantList::get(int index) {
if(index < 0) return QSharedPointer<NetVariant>(nullptr);
if(index >= variants.length()) return QSharedPointer<NetVariant>(nullptr);
return variants.at(index);
}
void NetVariantList::remove(int index) {
variants.removeAt(index);;
}
void NetVariantList::clear() {
variants.clear();
}
QString NetVariantList::debugDisplay()
{
QString result;
for(int x = 0; x < variants.length(); x++) {
result.append(variants.at(x)->getDisplayValue());
if(x < variants.length() - 1) {
result.append(", ");
}
}
return result;
}
extern "C" {
Q_DECL_EXPORT NetVariantListContainer* net_variant_list_create() {
NetVariantListContainer* result = new NetVariantListContainer();
result->list = QSharedPointer<NetVariantList>(new NetVariantList());
return result;
}
Q_DECL_EXPORT void net_variant_list_destroy(NetVariantListContainer* container) {
delete container;
}
Q_DECL_EXPORT int net_variant_list_count(NetVariantListContainer* container) {
return container->list->count();
}
Q_DECL_EXPORT void net_variant_list_add(NetVariantListContainer* container, NetVariantContainer* variant) {
container->list->add(variant->variant);
}
Q_DECL_EXPORT NetVariantContainer* net_variant_list_get(NetVariantListContainer* container, int index){
QSharedPointer<NetVariant> variant = container->list->get(index);
if(variant == nullptr) return nullptr;
NetVariantContainer* result = new NetVariantContainer();
result->variant = variant;
return result;
}
Q_DECL_EXPORT void net_variant_list_remove(NetVariantListContainer* container, int index) {
container->list->remove(index);
}
Q_DECL_EXPORT void net_variant_list_clear(NetVariantListContainer* container) {
container->list->clear();
}
}

View file

@ -1,27 +0,0 @@
#ifndef NETVARIANTLIST_H
#define NETVARIANTLIST_H
#include <QmlNet.h>
#include <QmlNet/qml/NetVariant.h>
#include <QSharedPointer>
class NetVariantList
{
public:
NetVariantList();
~NetVariantList();
int count();
void add(const QSharedPointer<NetVariant>& variant);
QSharedPointer<NetVariant> get(int index);
void remove(int index);
void clear();
QString debugDisplay();
private:
QList<QSharedPointer<NetVariant>> variants;
};
struct NetVariantListContainer {
QSharedPointer<NetVariantList> list;
};
#endif // NETVARIANTLIST_H

View file

@ -1,40 +0,0 @@
#include <QmlNet/qml/QCommon.h>
#include <QtGlobal>
#include <QString>
#include <QmlNetUtilities.h>
extern "C" {
Q_DECL_EXPORT uchar qt_putenv(LPCSTR name, LPCSTR value)
{
if(value == nullptr) {
if(qunsetenv(name)) {
return 1;
} else {
return 0;
}
} else {
if(qputenv(name, value)) {
return 1;
} else {
return 0;
}
}
}
Q_DECL_EXPORT QmlNetStringContainer* qt_getenv(LPCSTR name)
{
QByteArray result = qgetenv(name);
if(result.isNull()) {
return nullptr;
}
QString string = QString(result);
return createString(string);
}
Q_DECL_EXPORT QmlNetStringContainer* qt_version() {
QString version(qVersion());
return createString(version);
}
}

View file

@ -1,6 +0,0 @@
#ifndef NET_QCOMMON_H
#define NET_QCOMMON_H
#include <QmlNet.h>
#endif // NET_QCOMMON_H

View file

@ -1,213 +0,0 @@
#include <QmlNet/qml/QCoreApplication.h>
#include <QmlNet/qml/NetVariantList.h>
#include <QGuiApplication>
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QmlNetUtilities.h>
#include <QDebug>
GuiThreadContextTriggerCallback::GuiThreadContextTriggerCallback() :
_callbacks(nullptr)
{
}
GuiThreadContextTriggerCallback::~GuiThreadContextTriggerCallback()
{
if (_callbacks) {
delete _callbacks;
}
}
void GuiThreadContextTriggerCallback::trigger()
{
if (!_callbacks) {
qCritical("callbacks not registered");
return;
}
_callbacks->guiThreadTrigger();
}
void GuiThreadContextTriggerCallback::aboutToQuit()
{
if (!_callbacks) {
qCritical("callbacks not registered");
return;
}
_callbacks->aboutToQuit();
}
void GuiThreadContextTriggerCallback::setCallbacks(QCoreAppCallbacks* callbacks)
{
if (_callbacks) {
delete _callbacks;
_callbacks = nullptr;
}
if (callbacks) {
_callbacks = new QCoreAppCallbacks();
*_callbacks = *callbacks;
}
}
extern "C" {
Q_DECL_EXPORT QGuiApplicationContainer* qapp_fromExisting(QCoreApplication* rawPointer)
{
QGuiApplicationContainer* result = new QGuiApplicationContainer();
result->ownsApp = false;
result->app = rawPointer;
result->callback = QSharedPointer<GuiThreadContextTriggerCallback>(new GuiThreadContextTriggerCallback());
QObject::connect(result->app, SIGNAL(aboutToQuit()), result->callback.data(), SLOT(aboutToQuit()));
return result;
}
Q_DECL_EXPORT QGuiApplicationContainer* qapp_create(NetVariantListContainer* argsContainer, int flags, int type)
{
QGuiApplicationContainer* result = new QGuiApplicationContainer();
// Build our args
if(argsContainer != nullptr) {
QSharedPointer<NetVariantList> args = argsContainer->list;
for(int x = 0; x < args->count(); x++) {
QByteArray arg = args->get(x)->getString().toLatin1();
result->args.append(arg);
char* cstr = new char [size_t(arg.size())+1];
memcpy(cstr, arg.data(), size_t(arg.size())+1);
result->argsPointer.push_back(cstr);
}
result->argCount = result->args.size();
} else {
result->argCount = 0;
}
result->ownsApp = true;
switch(type)
{
case 0:
result->app = new QCoreApplication(result->argCount, &result->argsPointer[0], flags);
break;
case 1:
result->app = new QGuiApplication(result->argCount, &result->argsPointer[0], flags);
break;
case 2:
result->app = new QApplication(result->argCount, &result->argsPointer[0], flags);
break;
default:
qCritical("invalid app type %d", type);
delete result;
return nullptr;
}
result->callback = QSharedPointer<GuiThreadContextTriggerCallback>(new GuiThreadContextTriggerCallback());
QObject::connect(result->app, SIGNAL(aboutToQuit()), result->callback.data(), SLOT(aboutToQuit()));
return result;
}
Q_DECL_EXPORT void qapp_destroy(QGuiApplicationContainer* container)
{
for (auto i : container->argsPointer) {
delete[] i;
}
container->callback.clear();
if(container->ownsApp) {
delete container->app;
}
delete container;
}
Q_DECL_EXPORT int qapp_getType(QGuiApplicationContainer* container, QCoreApplication* rawPointer)
{
if (!container && !rawPointer) {
qCritical("invalid container and/or rawPointer");
return -1;
}
if (container && rawPointer) {
qCritical("invalid container and/or rawPointer");
return -1;
}
if(!rawPointer && container) {
rawPointer = container->app;
}
if (qobject_cast<QApplication*>(rawPointer) != nullptr){
return 2;
}
if (qobject_cast<QGuiApplication*>(rawPointer) != nullptr){
return 1;
}
// QCoreApplication
return 0;
}
Q_DECL_EXPORT void qapp_processEvents(QEventLoop::ProcessEventsFlags flags)
{
QCoreApplication::processEvents(flags);
}
Q_DECL_EXPORT void qapp_processEventsWithTimeout(QEventLoop::ProcessEventsFlags flags, int timeout)
{
QCoreApplication::processEvents(flags, timeout);
}
Q_DECL_EXPORT int qapp_exec()
{
return QGuiApplication::exec();
}
Q_DECL_EXPORT void qapp_addCallbacks(QGuiApplicationContainer* container, QCoreAppCallbacks* callbacks)
{
container->callback->setCallbacks(callbacks);
}
Q_DECL_EXPORT void qapp_requestTrigger(QGuiApplicationContainer* container)
{
QMetaObject::invokeMethod(container->callback.data(), "trigger", Qt::QueuedConnection);
}
Q_DECL_EXPORT void qapp_exit(int returnCode)
{
QGuiApplication::exit(returnCode);
}
Q_DECL_EXPORT QCoreApplication* qapp_internalPointer(QGuiApplicationContainer* container)
{
return container->app;
}
Q_DECL_EXPORT void qapp_setOrganizationName(LPWCSTR organizationName)
{
QCoreApplication::setOrganizationName(QString::fromUtf16(organizationName));
}
Q_DECL_EXPORT QmlNetStringContainer* qapp_getOrganizationName()
{
return createString(QCoreApplication::organizationName());
}
Q_DECL_EXPORT void qapp_setOrganizationDomain(LPWCSTR organizationDomain)
{
QCoreApplication::setOrganizationDomain(QString::fromUtf16(organizationDomain));
}
Q_DECL_EXPORT QmlNetStringContainer* qapp_getOrganizationDomain()
{
return createString(QCoreApplication::organizationDomain());
}
Q_DECL_EXPORT void qapp_setAttribute(int attribute, bool on)
{
QCoreApplication::setAttribute(static_cast<Qt::ApplicationAttribute>(attribute), on);
}
Q_DECL_EXPORT uchar qapp_testAttribute(int attribute)
{
if (QCoreApplication::testAttribute(static_cast<Qt::ApplicationAttribute>(attribute))) {
return 1;
} else {
return 0;
}
}
}

View file

@ -1,40 +0,0 @@
#ifndef NET_QGUIAPPLICATION_H
#define NET_QGUIAPPLICATION_H
#include <QmlNet.h>
#include <QGuiApplication>
#include <QSharedPointer>
typedef void (*guiThreadTriggerCb)();
using guiThreadTriggerCb = void (*)();
using aboutToQuitCb = void (*)();
struct Q_DECL_EXPORT QCoreAppCallbacks {
guiThreadTriggerCb guiThreadTrigger;
aboutToQuitCb aboutToQuit;
};
class GuiThreadContextTriggerCallback : public QObject {
Q_OBJECT
public:
GuiThreadContextTriggerCallback();
~GuiThreadContextTriggerCallback();
void setCallbacks(QCoreAppCallbacks* callbacks);
public slots:
void trigger();
void aboutToQuit();
private:
QCoreAppCallbacks* _callbacks;
};
struct QGuiApplicationContainer {
int argCount;
QList<QString> args;
std::vector<char*> argsPointer;
QCoreApplication* app;
bool ownsApp;
QSharedPointer<GuiThreadContextTriggerCallback> callback;
};
#endif // NET_QGUIAPPLICATION_H

View file

@ -1,470 +0,0 @@
#include <QmlNet/qml/QQmlApplicationEngine.h>
#include <QmlNet/types/NetTypeInfo.h>
#include <QmlNet/qml/NetValueType.h>
#include <QmlNet/types/Callbacks.h>
#include <QmlNet/qml/JsNetObject.h>
#include <QQmlContext>
static QQmlApplicationEngine* sharedQmlEngineValue = nullptr;
QQmlApplicationEngine* sharedQmlEngine()
{
if(sharedQmlEngineValue == nullptr) {
qWarning("An attempt was made to get a shared application engine, but it is NULL. .NET needs to know about it. Returning null, but expect segfaults.");
return nullptr;
}
return sharedQmlEngineValue;
}
static int netValueTypeNumber = 0;
#define NETVALUETYPE_CASE(N) \
case N: NetValueType<N>::init(typeInfo); return qmlRegisterType<NetValueType<(N)>>(uriString.toUtf8().data(), versionMajor, versionMinor, qmlNameString.toUtf8().data());
#define NETVALUETYPESINGLETON_CASE(N) \
case N: NetValueType<N>::init(typeInfo); return qmlRegisterSingletonType<NetValueType<N>>(uriString.toUtf8().data(), versionMajor, versionMinor, typeNameString.toUtf8().data(), NetValueType<N>::build);
extern "C" {
Q_DECL_EXPORT QQmlApplicationEngineContainer* qqmlapplicationengine_create(QQmlApplicationEngine* existingEngine) {
bool ownsEngine = true;
QQmlApplicationEngine* engine = nullptr;
if (existingEngine != nullptr) {
engine = existingEngine;
ownsEngine = false;
} else {
engine = new QQmlApplicationEngine();
ownsEngine = true;
}
sharedQmlEngineValue = engine;
JsNetObject* netObject = new JsNetObject();
engine->rootContext()->setContextProperty("Net", netObject);
return new QQmlApplicationEngineContainer{
engine,
netObject,
ownsEngine
};
}
Q_DECL_EXPORT void qqmlapplicationengine_destroy(QQmlApplicationEngineContainer* container) {
if(container->ownsEngine) {
delete container->qmlEngine;
}
delete container->netObject;
delete container;
}
Q_DECL_EXPORT void qqmlapplicationengine_load(QQmlApplicationEngineContainer* container, LPWSTR path) {
container->qmlEngine->load(QString::fromUtf16(static_cast<const char16_t*>(path)));
}
Q_DECL_EXPORT void qqmlapplicationengine_loadData(QQmlApplicationEngineContainer* container, LPWSTR dataString) {
container->qmlEngine->loadData(QByteArray::fromStdString(QString::fromUtf16(static_cast<const char16_t*>(dataString)).toStdString()));
}
Q_DECL_EXPORT int qqmlapplicationengine_registerType(NetTypeInfoContainer* typeContainer, LPWSTR uri, int versionMajor, int versionMinor, LPWSTR qmlName) {
QString uriString = QString::fromUtf16(static_cast<const char16_t*>(uri));
QString qmlNameString = QString::fromUtf16(static_cast<const char16_t*>(qmlName));
QSharedPointer<NetTypeInfo> typeInfo = typeContainer->netTypeInfo;
switch (++netValueTypeNumber) {
NETVALUETYPE_CASE(1)
NETVALUETYPE_CASE(2)
NETVALUETYPE_CASE(3)
NETVALUETYPE_CASE(4)
NETVALUETYPE_CASE(5)
NETVALUETYPE_CASE(6)
NETVALUETYPE_CASE(7)
NETVALUETYPE_CASE(8)
NETVALUETYPE_CASE(9)
NETVALUETYPE_CASE(10)
NETVALUETYPE_CASE(11)
NETVALUETYPE_CASE(12)
NETVALUETYPE_CASE(13)
NETVALUETYPE_CASE(14)
NETVALUETYPE_CASE(15)
NETVALUETYPE_CASE(16)
NETVALUETYPE_CASE(17)
NETVALUETYPE_CASE(18)
NETVALUETYPE_CASE(19)
NETVALUETYPE_CASE(20)
NETVALUETYPE_CASE(21)
NETVALUETYPE_CASE(22)
NETVALUETYPE_CASE(23)
NETVALUETYPE_CASE(24)
NETVALUETYPE_CASE(25)
NETVALUETYPE_CASE(26)
NETVALUETYPE_CASE(27)
NETVALUETYPE_CASE(28)
NETVALUETYPE_CASE(29)
NETVALUETYPE_CASE(30)
NETVALUETYPE_CASE(31)
NETVALUETYPE_CASE(32)
NETVALUETYPE_CASE(33)
NETVALUETYPE_CASE(34)
NETVALUETYPE_CASE(35)
NETVALUETYPE_CASE(36)
NETVALUETYPE_CASE(37)
NETVALUETYPE_CASE(38)
NETVALUETYPE_CASE(39)
NETVALUETYPE_CASE(40)
NETVALUETYPE_CASE(41)
NETVALUETYPE_CASE(42)
NETVALUETYPE_CASE(43)
NETVALUETYPE_CASE(44)
NETVALUETYPE_CASE(45)
NETVALUETYPE_CASE(46)
NETVALUETYPE_CASE(47)
NETVALUETYPE_CASE(48)
NETVALUETYPE_CASE(49)
NETVALUETYPE_CASE(50)
NETVALUETYPE_CASE(51)
NETVALUETYPE_CASE(52)
NETVALUETYPE_CASE(53)
NETVALUETYPE_CASE(54)
NETVALUETYPE_CASE(55)
NETVALUETYPE_CASE(56)
NETVALUETYPE_CASE(57)
NETVALUETYPE_CASE(58)
NETVALUETYPE_CASE(59)
NETVALUETYPE_CASE(60)
NETVALUETYPE_CASE(61)
NETVALUETYPE_CASE(62)
NETVALUETYPE_CASE(63)
NETVALUETYPE_CASE(64)
NETVALUETYPE_CASE(65)
NETVALUETYPE_CASE(66)
NETVALUETYPE_CASE(67)
NETVALUETYPE_CASE(68)
NETVALUETYPE_CASE(69)
NETVALUETYPE_CASE(70)
NETVALUETYPE_CASE(71)
NETVALUETYPE_CASE(72)
NETVALUETYPE_CASE(73)
NETVALUETYPE_CASE(74)
NETVALUETYPE_CASE(75)
NETVALUETYPE_CASE(76)
NETVALUETYPE_CASE(77)
NETVALUETYPE_CASE(78)
NETVALUETYPE_CASE(79)
NETVALUETYPE_CASE(80)
NETVALUETYPE_CASE(81)
NETVALUETYPE_CASE(82)
NETVALUETYPE_CASE(83)
NETVALUETYPE_CASE(84)
NETVALUETYPE_CASE(85)
NETVALUETYPE_CASE(86)
NETVALUETYPE_CASE(87)
NETVALUETYPE_CASE(88)
NETVALUETYPE_CASE(89)
NETVALUETYPE_CASE(90)
NETVALUETYPE_CASE(91)
NETVALUETYPE_CASE(92)
NETVALUETYPE_CASE(93)
NETVALUETYPE_CASE(94)
NETVALUETYPE_CASE(95)
NETVALUETYPE_CASE(96)
NETVALUETYPE_CASE(97)
NETVALUETYPE_CASE(98)
NETVALUETYPE_CASE(99)
NETVALUETYPE_CASE(100)
NETVALUETYPE_CASE(101)
NETVALUETYPE_CASE(102)
NETVALUETYPE_CASE(103)
NETVALUETYPE_CASE(104)
NETVALUETYPE_CASE(105)
NETVALUETYPE_CASE(106)
NETVALUETYPE_CASE(107)
NETVALUETYPE_CASE(108)
NETVALUETYPE_CASE(109)
NETVALUETYPE_CASE(110)
NETVALUETYPE_CASE(111)
NETVALUETYPE_CASE(112)
NETVALUETYPE_CASE(113)
NETVALUETYPE_CASE(114)
NETVALUETYPE_CASE(115)
NETVALUETYPE_CASE(116)
NETVALUETYPE_CASE(117)
NETVALUETYPE_CASE(118)
NETVALUETYPE_CASE(119)
NETVALUETYPE_CASE(120)
NETVALUETYPE_CASE(121)
NETVALUETYPE_CASE(122)
NETVALUETYPE_CASE(123)
NETVALUETYPE_CASE(124)
NETVALUETYPE_CASE(125)
NETVALUETYPE_CASE(126)
NETVALUETYPE_CASE(127)
NETVALUETYPE_CASE(128)
NETVALUETYPE_CASE(129)
NETVALUETYPE_CASE(130)
NETVALUETYPE_CASE(131)
NETVALUETYPE_CASE(132)
NETVALUETYPE_CASE(133)
NETVALUETYPE_CASE(134)
NETVALUETYPE_CASE(135)
NETVALUETYPE_CASE(136)
NETVALUETYPE_CASE(137)
NETVALUETYPE_CASE(138)
NETVALUETYPE_CASE(139)
NETVALUETYPE_CASE(140)
NETVALUETYPE_CASE(141)
NETVALUETYPE_CASE(142)
NETVALUETYPE_CASE(143)
NETVALUETYPE_CASE(144)
NETVALUETYPE_CASE(145)
NETVALUETYPE_CASE(146)
NETVALUETYPE_CASE(147)
NETVALUETYPE_CASE(148)
NETVALUETYPE_CASE(149)
NETVALUETYPE_CASE(150)
NETVALUETYPE_CASE(151)
NETVALUETYPE_CASE(152)
NETVALUETYPE_CASE(153)
NETVALUETYPE_CASE(154)
NETVALUETYPE_CASE(155)
NETVALUETYPE_CASE(156)
NETVALUETYPE_CASE(157)
NETVALUETYPE_CASE(158)
NETVALUETYPE_CASE(159)
NETVALUETYPE_CASE(160)
NETVALUETYPE_CASE(161)
NETVALUETYPE_CASE(162)
NETVALUETYPE_CASE(163)
NETVALUETYPE_CASE(164)
NETVALUETYPE_CASE(165)
NETVALUETYPE_CASE(166)
NETVALUETYPE_CASE(167)
NETVALUETYPE_CASE(168)
NETVALUETYPE_CASE(169)
NETVALUETYPE_CASE(170)
}
qFatal("Too many registered types: %d", netValueTypeNumber);
return -1;
}
Q_DECL_EXPORT int qqmlapplicationengine_registerSingletonTypeQml(LPWCSTR url, LPWCSTR uri, int versionMajor, int versionMinor, LPWCSTR qmlName)
{
QString urlString = QString::fromUtf16(url);
QString uriString = QString::fromUtf16(uri);
QString qmlNameString = QString::fromUtf16(qmlName);
return qmlRegisterSingletonType(urlString, uriString.toUtf8().data(), versionMajor, versionMinor, qmlNameString.toUtf8().data());
}
Q_DECL_EXPORT int qqmlapplicationengine_registerSingletonTypeNet(NetTypeInfoContainer* typeContainer, LPWCSTR uri, int versionMajor, int versionMinor, LPWCSTR typeName)
{
QSharedPointer<NetTypeInfo> typeInfo = typeContainer->netTypeInfo;
QString typeNameString = QString::fromUtf16(typeName);
QString uriString = QString::fromUtf16(uri);
switch (++netValueTypeNumber) {
NETVALUETYPESINGLETON_CASE(1)
NETVALUETYPESINGLETON_CASE(2)
NETVALUETYPESINGLETON_CASE(3)
NETVALUETYPESINGLETON_CASE(4)
NETVALUETYPESINGLETON_CASE(5)
NETVALUETYPESINGLETON_CASE(6)
NETVALUETYPESINGLETON_CASE(7)
NETVALUETYPESINGLETON_CASE(8)
NETVALUETYPESINGLETON_CASE(9)
NETVALUETYPESINGLETON_CASE(10)
NETVALUETYPESINGLETON_CASE(11)
NETVALUETYPESINGLETON_CASE(12)
NETVALUETYPESINGLETON_CASE(13)
NETVALUETYPESINGLETON_CASE(14)
NETVALUETYPESINGLETON_CASE(15)
NETVALUETYPESINGLETON_CASE(16)
NETVALUETYPESINGLETON_CASE(17)
NETVALUETYPESINGLETON_CASE(18)
NETVALUETYPESINGLETON_CASE(19)
NETVALUETYPESINGLETON_CASE(20)
NETVALUETYPESINGLETON_CASE(21)
NETVALUETYPESINGLETON_CASE(22)
NETVALUETYPESINGLETON_CASE(23)
NETVALUETYPESINGLETON_CASE(24)
NETVALUETYPESINGLETON_CASE(25)
NETVALUETYPESINGLETON_CASE(26)
NETVALUETYPESINGLETON_CASE(27)
NETVALUETYPESINGLETON_CASE(28)
NETVALUETYPESINGLETON_CASE(29)
NETVALUETYPESINGLETON_CASE(30)
NETVALUETYPESINGLETON_CASE(31)
NETVALUETYPESINGLETON_CASE(32)
NETVALUETYPESINGLETON_CASE(33)
NETVALUETYPESINGLETON_CASE(34)
NETVALUETYPESINGLETON_CASE(35)
NETVALUETYPESINGLETON_CASE(36)
NETVALUETYPESINGLETON_CASE(37)
NETVALUETYPESINGLETON_CASE(38)
NETVALUETYPESINGLETON_CASE(39)
NETVALUETYPESINGLETON_CASE(40)
NETVALUETYPESINGLETON_CASE(41)
NETVALUETYPESINGLETON_CASE(42)
NETVALUETYPESINGLETON_CASE(43)
NETVALUETYPESINGLETON_CASE(44)
NETVALUETYPESINGLETON_CASE(45)
NETVALUETYPESINGLETON_CASE(46)
NETVALUETYPESINGLETON_CASE(47)
NETVALUETYPESINGLETON_CASE(48)
NETVALUETYPESINGLETON_CASE(49)
NETVALUETYPESINGLETON_CASE(50)
NETVALUETYPESINGLETON_CASE(51)
NETVALUETYPESINGLETON_CASE(52)
NETVALUETYPESINGLETON_CASE(53)
NETVALUETYPESINGLETON_CASE(54)
NETVALUETYPESINGLETON_CASE(55)
NETVALUETYPESINGLETON_CASE(56)
NETVALUETYPESINGLETON_CASE(57)
NETVALUETYPESINGLETON_CASE(58)
NETVALUETYPESINGLETON_CASE(59)
NETVALUETYPESINGLETON_CASE(60)
NETVALUETYPESINGLETON_CASE(61)
NETVALUETYPESINGLETON_CASE(62)
NETVALUETYPESINGLETON_CASE(63)
NETVALUETYPESINGLETON_CASE(64)
NETVALUETYPESINGLETON_CASE(65)
NETVALUETYPESINGLETON_CASE(66)
NETVALUETYPESINGLETON_CASE(67)
NETVALUETYPESINGLETON_CASE(68)
NETVALUETYPESINGLETON_CASE(69)
NETVALUETYPESINGLETON_CASE(70)
NETVALUETYPESINGLETON_CASE(71)
NETVALUETYPESINGLETON_CASE(72)
NETVALUETYPESINGLETON_CASE(73)
NETVALUETYPESINGLETON_CASE(74)
NETVALUETYPESINGLETON_CASE(75)
NETVALUETYPESINGLETON_CASE(76)
NETVALUETYPESINGLETON_CASE(77)
NETVALUETYPESINGLETON_CASE(78)
NETVALUETYPESINGLETON_CASE(79)
NETVALUETYPESINGLETON_CASE(80)
NETVALUETYPESINGLETON_CASE(81)
NETVALUETYPESINGLETON_CASE(82)
NETVALUETYPESINGLETON_CASE(83)
NETVALUETYPESINGLETON_CASE(84)
NETVALUETYPESINGLETON_CASE(85)
NETVALUETYPESINGLETON_CASE(86)
NETVALUETYPESINGLETON_CASE(87)
NETVALUETYPESINGLETON_CASE(88)
NETVALUETYPESINGLETON_CASE(89)
NETVALUETYPESINGLETON_CASE(90)
NETVALUETYPESINGLETON_CASE(91)
NETVALUETYPESINGLETON_CASE(92)
NETVALUETYPESINGLETON_CASE(93)
NETVALUETYPESINGLETON_CASE(94)
NETVALUETYPESINGLETON_CASE(95)
NETVALUETYPESINGLETON_CASE(96)
NETVALUETYPESINGLETON_CASE(97)
NETVALUETYPESINGLETON_CASE(98)
NETVALUETYPESINGLETON_CASE(99)
NETVALUETYPESINGLETON_CASE(100)
NETVALUETYPESINGLETON_CASE(101)
NETVALUETYPESINGLETON_CASE(102)
NETVALUETYPESINGLETON_CASE(103)
NETVALUETYPESINGLETON_CASE(104)
NETVALUETYPESINGLETON_CASE(105)
NETVALUETYPESINGLETON_CASE(106)
NETVALUETYPESINGLETON_CASE(107)
NETVALUETYPESINGLETON_CASE(108)
NETVALUETYPESINGLETON_CASE(109)
NETVALUETYPESINGLETON_CASE(110)
NETVALUETYPESINGLETON_CASE(111)
NETVALUETYPESINGLETON_CASE(112)
NETVALUETYPESINGLETON_CASE(113)
NETVALUETYPESINGLETON_CASE(114)
NETVALUETYPESINGLETON_CASE(115)
NETVALUETYPESINGLETON_CASE(116)
NETVALUETYPESINGLETON_CASE(117)
NETVALUETYPESINGLETON_CASE(118)
NETVALUETYPESINGLETON_CASE(119)
NETVALUETYPESINGLETON_CASE(120)
NETVALUETYPESINGLETON_CASE(121)
NETVALUETYPESINGLETON_CASE(122)
NETVALUETYPESINGLETON_CASE(123)
NETVALUETYPESINGLETON_CASE(124)
NETVALUETYPESINGLETON_CASE(125)
NETVALUETYPESINGLETON_CASE(126)
NETVALUETYPESINGLETON_CASE(127)
NETVALUETYPESINGLETON_CASE(128)
NETVALUETYPESINGLETON_CASE(129)
NETVALUETYPESINGLETON_CASE(130)
NETVALUETYPESINGLETON_CASE(131)
NETVALUETYPESINGLETON_CASE(132)
NETVALUETYPESINGLETON_CASE(133)
NETVALUETYPESINGLETON_CASE(134)
NETVALUETYPESINGLETON_CASE(135)
NETVALUETYPESINGLETON_CASE(136)
NETVALUETYPESINGLETON_CASE(137)
NETVALUETYPESINGLETON_CASE(138)
NETVALUETYPESINGLETON_CASE(139)
NETVALUETYPESINGLETON_CASE(140)
NETVALUETYPESINGLETON_CASE(141)
NETVALUETYPESINGLETON_CASE(142)
NETVALUETYPESINGLETON_CASE(143)
NETVALUETYPESINGLETON_CASE(144)
NETVALUETYPESINGLETON_CASE(145)
NETVALUETYPESINGLETON_CASE(146)
NETVALUETYPESINGLETON_CASE(147)
NETVALUETYPESINGLETON_CASE(148)
NETVALUETYPESINGLETON_CASE(149)
NETVALUETYPESINGLETON_CASE(150)
NETVALUETYPESINGLETON_CASE(151)
NETVALUETYPESINGLETON_CASE(152)
NETVALUETYPESINGLETON_CASE(153)
NETVALUETYPESINGLETON_CASE(154)
NETVALUETYPESINGLETON_CASE(155)
NETVALUETYPESINGLETON_CASE(156)
NETVALUETYPESINGLETON_CASE(157)
NETVALUETYPESINGLETON_CASE(158)
NETVALUETYPESINGLETON_CASE(159)
NETVALUETYPESINGLETON_CASE(160)
NETVALUETYPESINGLETON_CASE(161)
NETVALUETYPESINGLETON_CASE(162)
NETVALUETYPESINGLETON_CASE(163)
NETVALUETYPESINGLETON_CASE(164)
NETVALUETYPESINGLETON_CASE(165)
NETVALUETYPESINGLETON_CASE(166)
NETVALUETYPESINGLETON_CASE(167)
NETVALUETYPESINGLETON_CASE(168)
NETVALUETYPESINGLETON_CASE(169)
NETVALUETYPESINGLETON_CASE(170)
}
qFatal("Too many registered types: %d", netValueTypeNumber);
return -1;
}
Q_DECL_EXPORT void qqmlapplicationengine_addImportPath(QQmlApplicationEngineContainer* container, LPWSTR path) {
QString pathString = QString::fromUtf16(static_cast<const char16_t*>(path));
container->qmlEngine->addImportPath(pathString);
}
Q_DECL_EXPORT QQmlApplicationEngine* qqmlapplicationengine_internalPointer(QQmlApplicationEngineContainer* container) {
return container->qmlEngine;
}
Q_DECL_EXPORT NetVariantContainer* qqmlapplicationengine_getContextProperty(QQmlApplicationEngineContainer* container, LPWCSTR name)
{
QVariant result = container->qmlEngine->rootContext()->contextProperty(QString::fromUtf16(name));
return new NetVariantContainer {
NetVariant::fromQVariant(&result)
};
}
Q_DECL_EXPORT void qqmlapplicationengine_setContextProperty(QQmlApplicationEngineContainer* container, LPWCSTR name, NetVariantContainer* valueContainer)
{
if(valueContainer == nullptr) {
container->qmlEngine->rootContext()->setContextProperty(QString::fromUtf16(name), nullptr);
} else {
QSharedPointer<NetVariant> value = valueContainer->variant;
container->qmlEngine->rootContext()->setContextProperty(QString::fromUtf16(name), value->toQVariant());
}
}
}

View file

@ -1,16 +0,0 @@
#ifndef NET_QQMLAPPLICATIONENGINE_H
#define NET_QQMLAPPLICATIONENGINE_H
#include <QmlNet.h>
#include <QQmlApplicationEngine>
#include <QmlNet/qml/JsNetObject.h>
QQmlApplicationEngine* sharedQmlEngine();
struct QQmlApplicationEngineContainer {
QQmlApplicationEngine* qmlEngine;
JsNetObject* netObject;
bool ownsEngine;
};
#endif // NET_QQMLAPPLICATIONENGINE_H

View file

@ -1,16 +0,0 @@
#include <QmlNet/qml/QQuickStyle.h>
#include <QQuickStyle>
extern "C" {
Q_DECL_EXPORT void qquickstyle_setFallbackStyle(LPWCSTR style)
{
QQuickStyle::setFallbackStyle(QString::fromUtf16(style));
}
Q_DECL_EXPORT void qquickstyle_setStyle(LPWCSTR style)
{
QQuickStyle::setStyle(QString::fromUtf16(style));
}
}

View file

@ -1,6 +0,0 @@
#ifndef NET_QQUICKSTYLE_H
#define NET_QQUICKSTYLE_H
#include <QmlNet.h>
#endif // NET_QQUICKSTYLE_H

View file

@ -1,27 +0,0 @@
#include <QmlNet/qml/QResource.h>
#include <QResource>
#include <QDir>
extern "C" {
Q_DECL_EXPORT uchar qresource_registerResource(LPWSTR rccFileName, LPWSTR resourceRoot) {
QString rccFileNameString = QString::fromUtf16(static_cast<const char16_t*>(rccFileName));
QString resourceRootString = QString::fromUtf16(static_cast<const char16_t*>(resourceRoot));
if(QResource::registerResource(rccFileNameString, resourceRootString)) {
return 1;
} else{
return 0;
}
}
Q_DECL_EXPORT uchar qresource_unregisterResource(LPWSTR rccFileName, LPWSTR resourceRoot) {
QString rccFileNameString = QString::fromUtf16(static_cast<const char16_t*>(rccFileName));
QString resourceRootString = QString::fromUtf16(static_cast<const char16_t*>(resourceRoot));
if(QResource::unregisterResource(rccFileNameString, resourceRootString)) {
return 1;
} else {
return 0;
}
}
}

View file

@ -1,6 +0,0 @@
#ifndef NET_QRESOURCE_H
#define NET_QRESOURCE_H
#include <QmlNet.h>
#endif // NET_QRESOURCE_H

View file

@ -1,31 +0,0 @@
#include "QTest.h"
#include <QtTest/qtestsystem.h>
using waitForCb = int (*)();
extern "C" {
Q_DECL_EXPORT void qtest_qwait(int ms)
{
QTest::qWait(ms);
}
Q_DECL_EXPORT int qtest_qWaitFor(waitForCb cb, int ms)
{
auto result = QTest::qWaitFor([&]() {
auto result = cb();
if (result == 1) {
return true;
} else {
return false;
}
}, ms);
if (result) {
return 1;
} else {
return 0;
}
}
}

View file

@ -1,6 +0,0 @@
#ifndef QTEST_H
#define QTEST_H
#include <QmlNet.h>
#endif // QTEST_H

View file

@ -1,17 +0,0 @@
#include <QmlNet/qml/QtWebEngine.h>
#ifdef QMLNET_WEBENGINE
#include <QtWebEngine>
#endif
extern "C" {
Q_DECL_EXPORT void qtwebebengine_initialize()
{
#ifdef QMLNET_WEBENGINE
QtWebEngine::initialize();
#else
qCritical("Qml.Net wasn't compiled with webengine.");
#endif
}
}

View file

@ -1,6 +0,0 @@
#ifndef QTWEBENGINE_H
#define QTWEBENGINE_H
#include <QmlNet.h>
#endif // QTWEBENGINE_H

View file

@ -1,43 +0,0 @@
HEADERS += \
$$PWD/QQmlApplicationEngine.h \
$$PWD/NetVariant.h \
$$PWD/NetValue.h \
$$PWD/NetValueMetaObject.h \
$$PWD/NetValueType.h \
$$PWD/NetVariantList.h \
$$PWD/NetTestHelper.h \
$$PWD/QResource.h \
$$PWD/JsNetObject.h \
$$PWD/NetJsValue.h \
$$PWD/QQuickStyle.h \
$$PWD/NetValueMetaObjectPacker.h \
$$PWD/QCommon.h \
$$PWD/NetListModel.h \
$$PWD/QtWebEngine.h \
$$PWD/QCoreApplication.h \
$$PWD/QTest.h \
$$PWD/NetQObject.h \
$$PWD/NetQObjectSignalConnection.h \
$$PWD/NetQObjectArg.h
SOURCES += \
$$PWD/QQmlApplicationEngine.cpp \
$$PWD/NetVariant.cpp \
$$PWD/NetValue.cpp \
$$PWD/NetValueMetaObject.cpp \
$$PWD/NetValueType.cpp \
$$PWD/NetVariantList.cpp \
$$PWD/NetTestHelper.cpp \
$$PWD/QResource.cpp \
$$PWD/JsNetObject.cpp \
$$PWD/NetJsValue.cpp \
$$PWD/QQuickStyle.cpp \
$$PWD/NetValueMetaObjectPacker.cpp \
$$PWD/QCommon.cpp \
$$PWD/NetListModel.cpp \
$$PWD/QtWebEngine.cpp \
$$PWD/QCoreApplication.cpp \
$$PWD/QTest.cpp \
$$PWD/NetQObject.cpp \
$$PWD/NetQObjectSignalConnection.cpp \
$$PWD/NetQObjectArg.cpp

View file

@ -1,236 +0,0 @@
#include <QmlNet/types/Callbacks.h>
#include <utility>
namespace QmlNet {
using isTypeValidCb = uchar (*)(LPWSTR);
using createLazyTypeInfoCb = void (*)(NetTypeInfoContainer *);
using loadTypeInfoCb = void (*)(NetTypeInfoContainer *);
using callComponentCompletedCb = void (*)(NetReferenceContainer *);
using callObjectDestroyedCb = void (*)(NetReferenceContainer *);
using releaseNetReferenceCb = void (*)(uint64_t);
using releaseNetDelegateGCHandleCb = void (*)(void *);
using instantiateTypeCb = NetReferenceContainer *(*)(NetTypeInfoContainer *);
using readPropertyCb = void (*)(NetPropertyInfoContainer *, NetReferenceContainer *, NetVariantContainer *, NetVariantContainer *);
using writePropertyCb = void (*)(NetPropertyInfoContainer *, NetReferenceContainer *, NetVariantContainer *, NetVariantContainer *);
using invokeMethodCb = void (*)(NetMethodInfoContainer *, NetReferenceContainer *, NetVariantListContainer *, NetVariantContainer *);
using gcCollectCb = void (*)(int);
using raiseNetSignalsCb = uchar (*)(NetReferenceContainer *, LPWCSTR, NetVariantListContainer *);
using awaitTaskCb = void (*)(NetReferenceContainer *, NetJSValueContainer *, NetJSValueContainer *);
using serializeNetToStringCb = uchar (*)(NetReferenceContainer *, NetVariantContainer *);
using invokeDelegateCb = void (*)(NetReferenceContainer *, NetVariantListContainer *);
struct Q_DECL_EXPORT NetTypeInfoManagerCallbacks {
isTypeValidCb isTypeValid;
createLazyTypeInfoCb createLazyTypeInfo;
loadTypeInfoCb loadTypeInfo;
callComponentCompletedCb callComponentCompleted;
callObjectDestroyedCb callObjectDestroyed;
releaseNetReferenceCb releaseNetReference;
releaseNetDelegateGCHandleCb releaseNetDelegateGCHandle;
instantiateTypeCb instantiateType;
readPropertyCb readProperty;
writePropertyCb writeProperty;
invokeMethodCb invokeMethod;
gcCollectCb gcCollect;
raiseNetSignalsCb raiseNetSignals;
awaitTaskCb awaitTask;
serializeNetToStringCb serializeNetToString;
invokeDelegateCb invokeDelegate;
};
static NetTypeInfoManagerCallbacks sharedCallbacks;
void buildTypeInfo(QSharedPointer<NetTypeInfo> typeInfo);
bool isTypeValid(const QString& type) {
static_assert (std::is_pointer<LPWSTR>::value, "Check the cast below.");
static_assert (!std::is_pointer<std::remove_pointer<LPWSTR>::type>::value, "Check the cast below.");
static_assert (sizeof(std::remove_pointer<LPWSTR>::type) == sizeof(ushort), "Check the cast below.");
return sharedCallbacks.isTypeValid(static_cast<LPWSTR>(const_cast<void*>(static_cast<const void*>(type.utf16())))) == 1;
}
void releaseNetReference(uint64_t objectId) {
return sharedCallbacks.releaseNetReference(objectId);
}
void releaseNetDelegateGCHandle(NetGCHandle* handle) {
return sharedCallbacks.releaseNetDelegateGCHandle(handle);
}
void createLazyTypeInfo(QSharedPointer<NetTypeInfo> typeInfo) {
NetTypeInfoContainer* container = new NetTypeInfoContainer();
container->netTypeInfo = std::move(typeInfo);
sharedCallbacks.createLazyTypeInfo(container);
}
void loadTypeInfo(QSharedPointer<NetTypeInfo> typeInfo) {
NetTypeInfoContainer* container = new NetTypeInfoContainer();
container->netTypeInfo = std::move(typeInfo);
sharedCallbacks.loadTypeInfo(container);
}
QSharedPointer<NetReference> instantiateType(QSharedPointer<NetTypeInfo> type) {
NetTypeInfoContainer* typeContainer = new NetTypeInfoContainer{ std::move(type) }; // .NET will delete this type
NetReferenceContainer* resultContainer = sharedCallbacks.instantiateType(typeContainer);
QSharedPointer<NetReference> result;
if(resultContainer != nullptr) {
result = resultContainer->instance;
// Special care is given here. .NET
// has given us a container that it will NOT delete itself.
// This means that .NET didn't wrap the pointer up in an object
// that will be GC'd.
delete resultContainer;
}
return result;
}
void callComponentCompleted(QSharedPointer<NetReference> target)
{
sharedCallbacks.callComponentCompleted(new NetReferenceContainer{target});
}
void callObjectDestroyed(QSharedPointer<NetReference> target)
{
sharedCallbacks.callObjectDestroyed(new NetReferenceContainer{target});
}
void readProperty(QSharedPointer<NetPropertyInfo> property, QSharedPointer<NetReference> target, const QSharedPointer<NetVariant>& indexParameter, QSharedPointer<NetVariant> result) {
NetPropertyInfoContainer* propertyContainer = new NetPropertyInfoContainer();
propertyContainer->property = std::move(property);
NetReferenceContainer* targetContainer = new NetReferenceContainer();
targetContainer->instance = std::move(target);
NetVariantContainer* indexParameterContainer = nullptr;
if(indexParameter != nullptr) {
indexParameterContainer = new NetVariantContainer{indexParameter};
}
NetVariantContainer* valueContainer = new NetVariantContainer();
valueContainer->variant = std::move(result);
sharedCallbacks.readProperty(propertyContainer, targetContainer, indexParameterContainer, valueContainer);
// The callbacks dispose of the types.
}
void writeProperty(QSharedPointer<NetPropertyInfo> property, QSharedPointer<NetReference> target, const QSharedPointer<NetVariant>& indexParameter, QSharedPointer<NetVariant> value) {
NetPropertyInfoContainer* propertyContainer = new NetPropertyInfoContainer();
propertyContainer->property = std::move(property);
NetReferenceContainer* targetContainer = new NetReferenceContainer();
targetContainer->instance = std::move(target);
NetVariantContainer* indexParameterContainer = nullptr;
if(indexParameter != nullptr) {
indexParameterContainer = new NetVariantContainer{indexParameter};
}
NetVariantContainer* resultContainer = new NetVariantContainer();
resultContainer->variant = std::move(value);
sharedCallbacks.writeProperty(propertyContainer, targetContainer, indexParameterContainer, resultContainer);
// The callbacks dispose of the types.
}
void invokeNetMethod(QSharedPointer<NetMethodInfo> method, QSharedPointer<NetReference> target, QSharedPointer<NetVariantList> parameters, const QSharedPointer<NetVariant>& result) {
NetMethodInfoContainer* methodContainer = new NetMethodInfoContainer();
methodContainer->method = std::move(method);
NetReferenceContainer* targetContainer = new NetReferenceContainer();
targetContainer->instance = std::move(target);
NetVariantListContainer* parametersContainer = new NetVariantListContainer();
parametersContainer->list = std::move(parameters);
NetVariantContainer* resultContainer = nullptr;
if(result != nullptr) {
// There is a return type.
resultContainer = new NetVariantContainer();
resultContainer->variant = result;
}
sharedCallbacks.invokeMethod(methodContainer, targetContainer, parametersContainer, resultContainer);
// The callbacks dispose of types.
}
void gcCollect(int maxGeneration) {
sharedCallbacks.gcCollect(maxGeneration);
}
bool raiseNetSignals(QSharedPointer<NetReference> target, const QString& signalName, const QSharedPointer<NetVariantList>& parameters) {
NetReferenceContainer* targetContainer = new NetReferenceContainer{std::move(target)};
NetVariantListContainer* parametersContainer = nullptr;
if(parameters != nullptr) {
parametersContainer = new NetVariantListContainer{parameters};
}
static_assert (std::is_pointer<LPWCSTR>::value, "Check the cast below.");
static_assert (!std::is_pointer<std::remove_pointer<LPWCSTR>::type>::value, "Check the cast below.");
static_assert (sizeof(std::remove_pointer<LPWCSTR>::type) == sizeof(ushort), "Check the cast below.");
return sharedCallbacks.raiseNetSignals(targetContainer, static_cast<LPWCSTR>(static_cast<const void*>(signalName.utf16())), parametersContainer) == 1;
}
void awaitTask(QSharedPointer<NetReference> target, QSharedPointer<NetJSValue> successCallback, const QSharedPointer<NetJSValue>& failureCallback) {
NetReferenceContainer* targetContainer = new NetReferenceContainer{std::move(target)};
NetJSValueContainer* sucessCallbackContainer = new NetJSValueContainer{std::move(successCallback)};
NetJSValueContainer* failureCallbackContainer = nullptr;
if(failureCallback != nullptr) {
failureCallbackContainer = new NetJSValueContainer{failureCallback};
}
sharedCallbacks.awaitTask(targetContainer, sucessCallbackContainer, failureCallbackContainer);
}
bool serializeNetToString(QSharedPointer<NetReference> instance, QSharedPointer<NetVariant> result)
{
return sharedCallbacks.serializeNetToString(new NetReferenceContainer{std::move(instance)},
new NetVariantContainer{std::move(result)}) == 1;
}
void invokeDelegate(QSharedPointer<NetReference> del, QSharedPointer<NetVariantList> parameters)
{
sharedCallbacks.invokeDelegate(new NetReferenceContainer{std::move(del)},
new NetVariantListContainer{std::move(parameters)});
}
}
extern "C" {
Q_DECL_EXPORT void type_info_callbacks_registerCallbacks(QmlNet::NetTypeInfoManagerCallbacks* callbacks) {
QmlNet::sharedCallbacks = *callbacks;
}
Q_DECL_EXPORT uchar type_info_callbacks_isTypeValid(LPWSTR typeName) {
return QmlNet::sharedCallbacks.isTypeValid(typeName);
}
Q_DECL_EXPORT void type_info_callbacks_releaseNetReferenceGCHandle(uint64_t objectId) {
QmlNet::sharedCallbacks.releaseNetReference(objectId);
}
Q_DECL_EXPORT void type_info_callbacks_releaseNetDelegateGCHandle(NetGCHandle* 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 QmlNet::sharedCallbacks.instantiateType(typeCopy);
}
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.
NetMethodInfoContainer* methodCopy = new NetMethodInfoContainer{method->method};
NetReferenceContainer* targetCopy = new NetReferenceContainer{target->instance};
NetVariantListContainer* parametersCopy = nullptr;
NetVariantContainer* resultCopy = nullptr;
if(parameters != nullptr) {
parametersCopy = new NetVariantListContainer{parameters->list};
}
if(result != nullptr) {
resultCopy = new NetVariantContainer{result->variant};
}
QmlNet::sharedCallbacks.invokeMethod(
methodCopy,
targetCopy,
parametersCopy,
resultCopy);
}
}

View file

@ -1,51 +0,0 @@
#ifndef NET_TYPE_INFO_MANAGER_H
#define NET_TYPE_INFO_MANAGER_H
#include <QmlNet.h>
#include <QmlNet/types/NetTypeInfo.h>
#include <QmlNet/types/NetPropertyInfo.h>
#include <QmlNet/types/NetMethodInfo.h>
#include <QmlNet/types/NetReference.h>
#include <QmlNet/qml/NetVariant.h>
#include <QmlNet/qml/NetVariantList.h>
#include <QmlNet/qml/NetJsValue.h>
#include <QSharedPointer>
#include <QString>
namespace QmlNet {
bool isTypeValid(const QString& type);
void releaseNetReference(uint64_t objectId);
void releaseNetDelegateGCHandle(NetGCHandle* handle);
void createLazyTypeInfo(QSharedPointer<NetTypeInfo> typeInfo);
void loadTypeInfo(QSharedPointer<NetTypeInfo> typeInfo);
QSharedPointer<NetReference> instantiateType(QSharedPointer<NetTypeInfo> type);
void callComponentCompleted(QSharedPointer<NetReference> target);
void callObjectDestroyed(QSharedPointer<NetReference> target);
void readProperty(QSharedPointer<NetPropertyInfo> property, QSharedPointer<NetReference> target, const QSharedPointer<NetVariant>& indexParameter, QSharedPointer<NetVariant> result);
void writeProperty(QSharedPointer<NetPropertyInfo> property, QSharedPointer<NetReference> target, const QSharedPointer<NetVariant>& indexParameter, QSharedPointer<NetVariant> value);
void invokeNetMethod(QSharedPointer<NetMethodInfo> method, QSharedPointer<NetReference> target, QSharedPointer<NetVariantList> parameters, const QSharedPointer<NetVariant>& result);
void gcCollect(int generation);
bool raiseNetSignals(QSharedPointer<NetReference> target, const QString& signalName, const QSharedPointer<NetVariantList>& parameters);
void awaitTask(QSharedPointer<NetReference> target, QSharedPointer<NetJSValue> successCallback, const QSharedPointer<NetJSValue>& failureCallback);
bool serializeNetToString(QSharedPointer<NetReference> instance, QSharedPointer<NetVariant> result);
void invokeDelegate(QSharedPointer<NetReference> del, QSharedPointer<NetVariantList> parameters);
}
#endif // NET_TYPE_INFO_MANAGER_H

View file

@ -1,33 +0,0 @@
#include <QmlNet/types/NetDelegate.h>
#include <QmlNet/types/Callbacks.h>
NetDelegate::NetDelegate(NetGCHandle* gcHandle) :
gcHandle(gcHandle) {
}
NetDelegate::~NetDelegate() {
QmlNet::releaseNetDelegateGCHandle(gcHandle);
}
NetGCHandle* NetDelegate::getGCHandle() {
return gcHandle;
}
extern "C" {
Q_DECL_EXPORT NetDelegateContainer* delegate_create(NetGCHandle* gcHandle) {
NetDelegateContainer* result = new NetDelegateContainer();
result->delegate = QSharedPointer<NetDelegate>(new NetDelegate(gcHandle));
return result;
}
Q_DECL_EXPORT void delegate_destroy(NetDelegateContainer* container) {
delete container;
}
Q_DECL_EXPORT NetGCHandle* delegate_getHandle(NetDelegateContainer* container) {
return container->delegate->getGCHandle();
}
}

View file

@ -1,21 +0,0 @@
#ifndef NETDELEGATE_H
#define NETDELEGATE_H
#include <QmlNet.h>
#include <QSharedPointer>
class NetDelegate
{
public:
NetDelegate(NetGCHandle* gcHandle);
~NetDelegate();
NetGCHandle* getGCHandle();
private:
NetGCHandle* gcHandle;
};
struct NetDelegateContainer {
QSharedPointer<NetDelegate> delegate;
};
#endif // NETDELEGATE_H

View file

@ -1,210 +0,0 @@
#include <QmlNet/types/NetMethodInfo.h>
#include <QmlNet/qml/NetValueMetaObjectPacker.h>
#include <QmlNetUtilities.h>
#include <QMutex>
#include <utility>
static int nextMethodId = 1;
Q_GLOBAL_STATIC(QMutex, methodIdMutex);
NetMethodInfoArguement::NetMethodInfoArguement(QString name,
QSharedPointer<NetTypeInfo> type) :
_name(std::move(name)),
_type(std::move(type))
{
}
QString NetMethodInfoArguement::getName()
{
return _name;
}
QSharedPointer<NetTypeInfo> NetMethodInfoArguement::getType()
{
return _type;
}
NetMethodInfo::NetMethodInfo(QSharedPointer<NetTypeInfo> parentTypeInfo,
QString methodName,
QSharedPointer<NetTypeInfo> returnType,
bool isStatic) :
_parentTypeInfo(std::move(parentTypeInfo)),
_methodName(std::move(methodName)),
_returnType(std::move(returnType)),
_isStatic(isStatic)
{
methodIdMutex->lock();
_id = nextMethodId;
nextMethodId++;
methodIdMutex->unlock();
}
int NetMethodInfo::getId()
{
return _id;
}
QSharedPointer<NetTypeInfo> NetMethodInfo::getParentType()
{
return _parentTypeInfo;
}
QString NetMethodInfo::getMethodName()
{
return _methodName;
}
QSharedPointer<NetTypeInfo> NetMethodInfo::getReturnType()
{
return _returnType;
}
bool NetMethodInfo::isStatic()
{
return _isStatic;
}
void NetMethodInfo::addParameter(QString name, QSharedPointer<NetTypeInfo> typeInfo)
{
_parameters.append(QSharedPointer<NetMethodInfoArguement>(new NetMethodInfoArguement(std::move(name), std::move(typeInfo))));
}
int NetMethodInfo::getParameterCount()
{
return _parameters.size();
}
QSharedPointer<NetMethodInfoArguement> NetMethodInfo::getParameter(int index)
{
if(index < 0) return QSharedPointer<NetMethodInfoArguement>(nullptr);
if(index >= _parameters.length()) return QSharedPointer<NetMethodInfoArguement>(nullptr);
return _parameters.at(index);
}
QString NetMethodInfo::getSignature()
{
QString signature = _methodName;
if(signature.at(0).isUpper()) {
signature.replace(0,1, signature.at(0).toLower());
}
signature.append("(");
for(int parameterIndex = 0; parameterIndex <= _parameters.size() - 1; parameterIndex++)
{
QSharedPointer<NetMethodInfoArguement> parameter = _parameters.at(parameterIndex);
QSharedPointer<NetTypeInfo> parameterType = parameter->getType();
if(parameterIndex > 0) {
signature.append(",");
}
signature.append(NetMetaValueQmlType(parameterType->getPrefVariantType()));
}
signature.append(")");
return signature;
}
extern "C" {
Q_DECL_EXPORT void method_info_parameter_destroy(NetMethodInfoArguementContainer* container)
{
delete container;
}
Q_DECL_EXPORT QmlNetStringContainer* method_info_parameter_getName(NetMethodInfoArguementContainer* container)
{
QString result = container->methodArguement->getName();
return createString(result);
}
Q_DECL_EXPORT NetTypeInfoContainer* method_info_parameter_getType(NetMethodInfoArguementContainer* container)
{
NetTypeInfoContainer* result = new NetTypeInfoContainer();
result->netTypeInfo = container->methodArguement->getType();
return result;
}
Q_DECL_EXPORT NetMethodInfoContainer* method_info_create(NetTypeInfoContainer* parentTypeContainer, LPWSTR methodName, NetTypeInfoContainer* returnTypeContainer, uchar isStatic)
{
NetMethodInfoContainer* result = new NetMethodInfoContainer();
QSharedPointer<NetTypeInfo> parentType;
if(parentTypeContainer != nullptr) {
parentType = parentTypeContainer->netTypeInfo;
}
QSharedPointer<NetTypeInfo> returnType;
if(returnTypeContainer != nullptr) {
returnType = returnTypeContainer->netTypeInfo;
}
NetMethodInfo* instance = new NetMethodInfo(parentType, QString::fromUtf16(static_cast<const char16_t*>(methodName)), returnType, isStatic == 1 ? true : false);
result->method = QSharedPointer<NetMethodInfo>(instance);
return result;
}
Q_DECL_EXPORT void method_info_destroy(NetMethodInfoContainer* container)
{
delete container;
}
Q_DECL_EXPORT int method_info_getId(NetMethodInfoContainer* container)
{
return container->method->getId();
}
Q_DECL_EXPORT NetTypeInfoContainer* method_info_getParentType(NetMethodInfoContainer* container)
{
return new NetTypeInfoContainer{container->method->getParentType()};
}
Q_DECL_EXPORT QmlNetStringContainer* method_info_getMethodName(NetMethodInfoContainer* container)
{
QString methodName = container->method->getMethodName();
return createString(methodName);
}
Q_DECL_EXPORT NetTypeInfoContainer* method_info_getReturnType(NetMethodInfoContainer* container)
{
QSharedPointer<NetTypeInfo> returnType = container->method->getReturnType();
if(returnType == nullptr) {
return nullptr;
}
NetTypeInfoContainer* result = new NetTypeInfoContainer();
result->netTypeInfo = returnType;
return result;
}
Q_DECL_EXPORT uchar method_info_isStatic(NetMethodInfoContainer* container)
{
if(container->method->isStatic()) {
return 1;
} else {
return 0;
}
}
Q_DECL_EXPORT void method_info_addParameter(NetMethodInfoContainer* container, LPWSTR name, NetTypeInfoContainer* typeInfoContainer)
{
container->method->addParameter(QString::fromUtf16(static_cast<const char16_t*>(name)), typeInfoContainer->netTypeInfo);
}
Q_DECL_EXPORT int method_info_getParameterCount(NetMethodInfoContainer* container)
{
return container->method->getParameterCount();
}
Q_DECL_EXPORT NetMethodInfoArguementContainer* method_info_getParameter(NetMethodInfoContainer* container, int index)
{
QSharedPointer<NetMethodInfoArguement> parameter = container->method->getParameter(index);
if(parameter == nullptr) {
return nullptr;
}
NetMethodInfoArguementContainer* result = new NetMethodInfoArguementContainer();
result->methodArguement = parameter;
return result;
}
}

View file

@ -1,59 +0,0 @@
#ifndef NET_TYPE_INFO_METHOD_H
#define NET_TYPE_INFO_METHOD_H
#include <QmlNet/types/NetTypeInfo.h>
#include <QSharedPointer>
class NetTypeInfo;
class NetMethodInfoArguement {
public:
NetMethodInfoArguement(QString name, QSharedPointer<NetTypeInfo> type);
QString getName();
QSharedPointer<NetTypeInfo> getType();
private:
QString _name;
QSharedPointer<NetTypeInfo> _type;
};
class NetMethodInfo {
public:
NetMethodInfo(QSharedPointer<NetTypeInfo> parentTypeInfo,
QString methodName,
QSharedPointer<NetTypeInfo> returnType,
bool isStatic);
int getId();
QSharedPointer<NetTypeInfo> getParentType();
QString getMethodName();
QSharedPointer<NetTypeInfo> getReturnType();
bool isStatic();
void addParameter(QString name, QSharedPointer<NetTypeInfo> typeInfo);
int getParameterCount();
QSharedPointer<NetMethodInfoArguement> getParameter(int index);
QString getSignature();
private:
int _id;
QSharedPointer<NetTypeInfo> _parentTypeInfo;
QString _methodName;
QSharedPointer<NetTypeInfo> _returnType;
bool _isStatic;
QList<QSharedPointer<NetMethodInfoArguement>> _parameters;
};
struct NetMethodInfoContainer {
QSharedPointer<NetMethodInfo> method;
};
struct NetMethodInfoArguementContainer {
QSharedPointer<NetMethodInfoArguement> methodArguement;
};
#endif // NET_TYPE_INFO_METHOD_H

View file

@ -1,185 +0,0 @@
#include <QmlNet/types/NetPropertyInfo.h>
#include <QmlNet/types/NetSignalInfo.h>
#include <QmlNetUtilities.h>
#include <QMutex>
#include <utility>
static int nextPropertyId = 1;
Q_GLOBAL_STATIC(QMutex, propertyIdMutex);
NetPropertyInfo::NetPropertyInfo(QSharedPointer<NetTypeInfo> parentType,
QString name,
QSharedPointer<NetTypeInfo> returnType,
bool canRead,
bool canWrite,
QSharedPointer<NetSignalInfo> notifySignal) :
_parentType(std::move(parentType)),
_name(std::move(name)),
_returnType(std::move(returnType)),
_canRead(canRead),
_canWrite(canWrite),
_notifySignal(std::move(notifySignal))
{
propertyIdMutex->lock();
_id = nextPropertyId;
nextPropertyId++;
propertyIdMutex->unlock();
}
int NetPropertyInfo::getId()
{
return _id;
}
QSharedPointer<NetTypeInfo> NetPropertyInfo::getParentType()
{
return _parentType;
}
QString NetPropertyInfo::getPropertyName()
{
return _name;
}
QSharedPointer<NetTypeInfo> NetPropertyInfo::getReturnType()
{
return _returnType;
}
bool NetPropertyInfo::canRead()
{
return _canRead;
}
bool NetPropertyInfo::canWrite()
{
return _canWrite;
}
QSharedPointer<NetSignalInfo> NetPropertyInfo::getNotifySignal()
{
return _notifySignal;
}
void NetPropertyInfo::setNotifySignal(QSharedPointer<NetSignalInfo> signal)
{
_notifySignal = std::move(signal);
}
void NetPropertyInfo::addIndexParameter(QString name, QSharedPointer<NetTypeInfo> typeInfo)
{
_indexParameters.append(QSharedPointer<NetMethodInfoArguement>(new NetMethodInfoArguement(std::move(name), std::move(typeInfo))));
}
int NetPropertyInfo::getIndexParameterCount()
{
return _indexParameters.size();
}
QSharedPointer<NetMethodInfoArguement> NetPropertyInfo::getIndexParameter(int index)
{
if(index < 0) return QSharedPointer<NetMethodInfoArguement>(nullptr);
if(index >= _indexParameters.length()) return QSharedPointer<NetMethodInfoArguement>(nullptr);
return _indexParameters.at(index);
}
extern "C" {
Q_DECL_EXPORT NetPropertyInfoContainer* property_info_create(NetTypeInfoContainer* parentTypeContainer,
LPWSTR name,
NetTypeInfoContainer* returnType,
uchar canRead,
uchar canWrite,
NetSignalInfoContainer* notifySignalContainer) {
NetPropertyInfoContainer* result = new NetPropertyInfoContainer();
QSharedPointer<NetSignalInfo> notifySignal;
if(notifySignalContainer != nullptr) {
notifySignal = notifySignalContainer->signal;
}
NetPropertyInfo* instance = new NetPropertyInfo(parentTypeContainer->netTypeInfo,
QString::fromUtf16(static_cast<const char16_t*>(name)),
returnType->netTypeInfo,
canRead == 1 ? true : false,
canWrite == 1 ? true : false,
notifySignal);
result->property = QSharedPointer<NetPropertyInfo>(instance);
return result;
}
Q_DECL_EXPORT void property_info_destroy(NetTypeInfoContainer* container) {
delete container;
}
Q_DECL_EXPORT int property_info_getId(NetPropertyInfoContainer* container)
{
return container->property->getId();
}
Q_DECL_EXPORT NetTypeInfoContainer* property_info_getParentType(NetPropertyInfoContainer* container) {
NetTypeInfoContainer* result = new NetTypeInfoContainer();
result->netTypeInfo = container->property->getParentType();
return result;
}
Q_DECL_EXPORT QmlNetStringContainer* property_info_getPropertyName(NetPropertyInfoContainer* container) {
QString result = container->property->getPropertyName();
return createString(result);
}
Q_DECL_EXPORT NetTypeInfoContainer* property_info_getReturnType(NetPropertyInfoContainer* container) {
NetTypeInfoContainer* result = new NetTypeInfoContainer();
result->netTypeInfo = container->property->getReturnType();
return result;
}
Q_DECL_EXPORT uchar property_info_canRead(NetPropertyInfoContainer* container) {
if(container->property->canRead()) {
return 1;
} else {
return 0;
}
}
Q_DECL_EXPORT uchar property_info_canWrite(NetPropertyInfoContainer* container) {
if(container->property->canWrite()) {
return 1;
} else {
return 0;
}
}
Q_DECL_EXPORT NetSignalInfoContainer* property_info_getNotifySignal(NetPropertyInfoContainer* container) {
QSharedPointer<NetSignalInfo> notifySignal = container->property->getNotifySignal();
if(notifySignal == nullptr) {
return nullptr;
}
return new NetSignalInfoContainer{notifySignal};
}
Q_DECL_EXPORT void property_info_setNotifySignal(NetPropertyInfoContainer* container, NetSignalInfoContainer* signalContainer) {
container->property->setNotifySignal(signalContainer->signal);
}
Q_DECL_EXPORT void property_info_addIndexParameter(NetPropertyInfoContainer* container, LPWCSTR name, NetTypeInfoContainer* typeInfoContainer)
{
container->property->addIndexParameter(QString::fromUtf16(name), typeInfoContainer->netTypeInfo);
}
Q_DECL_EXPORT int property_info_getIndexParameterCount(NetPropertyInfoContainer* container)
{
return container->property->getIndexParameterCount();
}
Q_DECL_EXPORT NetMethodInfoArguementContainer* property_info_getIndexParameter(NetPropertyInfoContainer* container, int index)
{
QSharedPointer<NetMethodInfoArguement> parameter = container->property->getIndexParameter(index);
if(parameter == nullptr) {
return nullptr;
}
NetMethodInfoArguementContainer* result = new NetMethodInfoArguementContainer();
result->methodArguement = parameter;
return result;
}
}

View file

@ -1,41 +0,0 @@
#ifndef NET_TYPE_INFO_PROPERTY_H
#define NET_TYPE_INFO_PROPERTY_H
#include <QmlNet/types/NetTypeInfo.h>
#include <QmlNet/types/NetMethodInfo.h>
class NetPropertyInfo {
public:
NetPropertyInfo(QSharedPointer<NetTypeInfo> parentType,
QString name,
QSharedPointer<NetTypeInfo> returnType,
bool canRead,
bool canWrite,
QSharedPointer<NetSignalInfo> notifySignal);
int getId();
QSharedPointer<NetTypeInfo> getParentType();
QString getPropertyName();
QSharedPointer<NetTypeInfo> getReturnType();
bool canRead();
bool canWrite();
QSharedPointer<NetSignalInfo> getNotifySignal();
void setNotifySignal(QSharedPointer<NetSignalInfo> signal);
void addIndexParameter(QString name, QSharedPointer<NetTypeInfo> typeInfo);
int getIndexParameterCount();
QSharedPointer<NetMethodInfoArguement> getIndexParameter(int index);
private:
int _id;
QSharedPointer<NetTypeInfo> _parentType;
QString _name;
QSharedPointer<NetTypeInfo> _returnType;
bool _canRead;
bool _canWrite;
QSharedPointer<NetSignalInfo> _notifySignal;
QList<QSharedPointer<NetMethodInfoArguement>> _indexParameters;
};
struct NetPropertyInfoContainer {
QSharedPointer<NetPropertyInfo> property;
};
#endif // NET_TYPE_INFO_PROPERTY_H

View file

@ -1,84 +0,0 @@
#include <QmlNet/types/NetReference.h>
#include <QmlNet/types/Callbacks.h>
#include <QmlNet/qml/NetValue.h>
#include <QDebug>
#include <utility>
NetReference::NetReference(uint64_t objectId, QSharedPointer<NetTypeInfo> typeInfo) :
objectId(objectId),
typeInfo(std::move(typeInfo))
{
}
NetReference::~NetReference()
{
QmlNet::releaseNetReference(objectId);
}
uint64_t NetReference::getObjectId()
{
return objectId;
}
QSharedPointer<NetTypeInfo> NetReference::getTypeInfo()
{
return typeInfo;
}
QString NetReference::displayName()
{
QString result = typeInfo->getClassName();
result.append("(");
result.append(QVariant::fromValue(objectId).toString());
result.append(")");
return result;
}
extern "C" {
Q_DECL_EXPORT NetReferenceContainer* net_instance_create(uint64_t objectId, NetTypeInfoContainer* typeContainer) {
NetReferenceContainer* result = new NetReferenceContainer();
result->instance = QSharedPointer<NetReference>(new NetReference(objectId, typeContainer->netTypeInfo));
return result;
}
Q_DECL_EXPORT void net_instance_destroy(NetReferenceContainer* container) {
delete container;
}
Q_DECL_EXPORT NetReferenceContainer* net_instance_clone(NetReferenceContainer* container) {
NetReferenceContainer* result = new NetReferenceContainer{container->instance};
return result;
}
Q_DECL_EXPORT uint64_t net_instance_getObjectId(NetReferenceContainer* container) {
return container->instance->getObjectId();
}
Q_DECL_EXPORT uchar net_instance_activateSignal(NetReferenceContainer* container, LPWCSTR signalName, NetVariantListContainer* parametersContainer) {
QList<NetValue*> liveInstances = NetValue::getAllLiveInstances(container->instance);
if(liveInstances.length() == 0) {
// Not alive in the QML world, so no signals to raise
return false;
}
QString signalNameString = QString::fromUtf16(signalName);
QSharedPointer<NetVariantList> parameters;
if(parametersContainer != nullptr) {
parameters = parametersContainer->list;
}
bool result = false;
for(NetValue* liveInstance : liveInstances) {
result = result || liveInstance->activateSignal(signalNameString, parameters);
}
if(result) {
return 1;
} else {
return 0;
}
}
}

View file

@ -1,23 +0,0 @@
#ifndef NetReference_H
#define NetReference_H
#include <QmlNet/types/NetTypeInfo.h>
class NetReference
{
public:
NetReference(uint64_t objectId, QSharedPointer<NetTypeInfo> typeInfo);
~NetReference();
uint64_t getObjectId();
QSharedPointer<NetTypeInfo> getTypeInfo();
QString displayName();
private:
uint64_t objectId;
QSharedPointer<NetTypeInfo> typeInfo;
};
struct NetReferenceContainer {
QSharedPointer<NetReference> instance;
};
#endif // NetReference_H

View file

@ -1,123 +0,0 @@
#include <QmlNet/types/NetSignalInfo.h>
#include <QmlNet/qml/NetValueMetaObjectPacker.h>
#include <QmlNetUtilities.h>
#include <utility>
NetSignalInfo::NetSignalInfo(QSharedPointer<NetTypeInfo> parentType, QString name) :
_parentType(std::move(parentType)),
_name(std::move(name))
{
}
QSharedPointer<NetTypeInfo> NetSignalInfo::getParentType()
{
return _parentType;
}
QString NetSignalInfo::getName()
{
return _name;
}
void NetSignalInfo::addParameter(NetVariantTypeEnum type)
{
if(type == NetVariantTypeEnum_Invalid) return;
_parameters.append(type);
}
int NetSignalInfo::getParameterCount()
{
return _parameters.size();
}
NetVariantTypeEnum NetSignalInfo::getParameter(int index)
{
if(index < 0) return NetVariantTypeEnum_Invalid;
if(index >= _parameters.length()) return NetVariantTypeEnum_Invalid;
return _parameters.at(index);
}
QString NetSignalInfo::getSignature()
{
QString signature = _name;
signature.append("(");
for(int parameterIndex = 0; parameterIndex <= _parameters.size() - 1; parameterIndex++)
{
if(parameterIndex > 0) {
signature.append(",");
}
signature.append(NetMetaValueQmlType(_parameters.at(parameterIndex)));
}
signature.append(")");
return signature;
}
QString NetSignalInfo::getSlotSignature()
{
QString signature = _name;
signature.append("_internal_slot_for_net_del(");
if(!_parameters.empty()) {
for(int parameterIndex = 0; parameterIndex <= _parameters.size() - 1; parameterIndex++)
{
if(parameterIndex > 0) {
signature.append(",");
}
signature.append(NetMetaValueQmlType(_parameters.at(parameterIndex)));
}
}
signature.append(")");
return signature;
}
extern "C" {
Q_DECL_EXPORT NetSignalInfoContainer* signal_info_create(NetTypeInfoContainer* parentTypeContainer, LPWSTR name)
{
NetSignalInfoContainer* result = new NetSignalInfoContainer();
NetSignalInfo* instance = new NetSignalInfo(parentTypeContainer->netTypeInfo, QString::fromUtf16(static_cast<const char16_t*>(name)));
result->signal = QSharedPointer<NetSignalInfo>(instance);
return result;
}
Q_DECL_EXPORT void signal_info_destroy(NetSignalInfoContainer* container)
{
delete container;
}
Q_DECL_EXPORT NetTypeInfoContainer* signal_info_getParentType(NetSignalInfoContainer* container)
{
NetTypeInfoContainer* result = new NetTypeInfoContainer{container->signal->getParentType()};
return result;
}
Q_DECL_EXPORT QmlNetStringContainer* signal_info_getName(NetSignalInfoContainer* container)
{
QString result = container->signal->getName();
return createString(result);
}
Q_DECL_EXPORT void signal_info_addParameter(NetSignalInfoContainer* container, NetVariantTypeEnum type)
{
container->signal->addParameter(type);
}
Q_DECL_EXPORT int signal_info_getParameterCount(NetSignalInfoContainer* container)
{
return container->signal->getParameterCount();
}
Q_DECL_EXPORT NetVariantTypeEnum signal_info_getParameter(NetSignalInfoContainer* container, int index)
{
return container->signal->getParameter(index);
}
}

View file

@ -1,28 +0,0 @@
#ifndef NET_SIGNAL_INFO_METHOD_H
#define NET_SIGNAL_INFO_METHOD_H
#include <QmlNet.h>
#include <QmlNet/types/NetTypeInfo.h>
#include <QSharedPointer>
class NetSignalInfo {
public:
NetSignalInfo(QSharedPointer<NetTypeInfo> parentType, QString name);
QSharedPointer<NetTypeInfo> getParentType();
QString getName();
void addParameter(NetVariantTypeEnum type);
int getParameterCount();
NetVariantTypeEnum getParameter(int index);
QString getSignature();
QString getSlotSignature();
private:
QSharedPointer<NetTypeInfo> _parentType;
QString _name;
QList<NetVariantTypeEnum> _parameters;
};
struct NetSignalInfoContainer {
QSharedPointer<NetSignalInfo> signal;
};
#endif // NET_SIGNAL_INFO_METHOD_H

View file

@ -1,62 +0,0 @@
#include <QmlNet/types/NetTypeArrayFacade.h>
#include <QmlNet/types/NetTypeArrayFacadeArray.h>
#include <QmlNet/types/NetTypeArrayFacadeList.h>
#include <QmlNet/types/NetTypeInfo.h>
NetTypeArrayFacade::NetTypeArrayFacade() = default;
QSharedPointer<NetTypeArrayFacade> NetTypeArrayFacade::fromType(const QSharedPointer<NetTypeInfo>& type)
{
if(type->isArray()) {
QSharedPointer<NetTypeArrayFacade_Array> facade = QSharedPointer<NetTypeArrayFacade_Array>(new NetTypeArrayFacade_Array(type));
if(facade->isIncomplete()) {
return nullptr;
}
return facade.staticCast<NetTypeArrayFacade>();
}
if(type->isList()) {
QSharedPointer<NetTypeArrayFacade_List> facade = QSharedPointer<NetTypeArrayFacade_List>(new NetTypeArrayFacade_List(type));
if(facade->isIncomplete()) {
return nullptr;
}
return facade.staticCast<NetTypeArrayFacade>();
}
return nullptr;
}
bool NetTypeArrayFacade::isFixed()
{
return false;
}
uint NetTypeArrayFacade::getLength(const QSharedPointer<NetReference>&)
{
return 0;
}
QSharedPointer<NetVariant> NetTypeArrayFacade::getIndexed(const QSharedPointer<NetReference>&, uint)
{
return nullptr;
}
void NetTypeArrayFacade::setIndexed(const QSharedPointer<NetReference>&, uint, const QSharedPointer<NetVariant>&)
{
}
void NetTypeArrayFacade::push(const QSharedPointer<NetReference>&, const QSharedPointer<NetVariant>&)
{
}
QSharedPointer<NetVariant> NetTypeArrayFacade::pop(const QSharedPointer<NetReference>&)
{
return nullptr;
}
void NetTypeArrayFacade::deleteAt(const QSharedPointer<NetReference>&, uint)
{
}

View file

@ -1,26 +0,0 @@
#ifndef NETTYPEARRAYFACADE_H
#define NETTYPEARRAYFACADE_H
#include <QmlNet.h>
#include <QSharedPointer>
class NetTypeInfo;
class NetReference;
class NetVariant;
class NetTypeArrayFacade
{
public:
NetTypeArrayFacade();
virtual ~NetTypeArrayFacade() {}
static QSharedPointer<NetTypeArrayFacade> fromType(const QSharedPointer<NetTypeInfo>& type);
virtual bool isFixed();
virtual uint getLength(const QSharedPointer<NetReference>& reference);
virtual QSharedPointer<NetVariant> getIndexed(const QSharedPointer<NetReference>& reference, uint index);
virtual void setIndexed(const QSharedPointer<NetReference>& reference, uint index, const QSharedPointer<NetVariant>& value);
virtual void push(const QSharedPointer<NetReference>& reference, const QSharedPointer<NetVariant>& value);
virtual QSharedPointer<NetVariant> pop(const QSharedPointer<NetReference>& reference);
virtual void deleteAt(const QSharedPointer<NetReference>& reference, uint index);
};
#endif // NETTYPEARRAYFACADE_H

View file

@ -1,74 +0,0 @@
#include <QmlNet/types/NetTypeArrayFacadeArray.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_Array::NetTypeArrayFacade_Array(const QSharedPointer<NetTypeInfo>& type) :
_isIncomplete(false)
{
for(int x = 0; x < type->getPropertyCount(); x++) {
QSharedPointer<NetPropertyInfo> property = type->getProperty(x);
if(property->getPropertyName().compare("Length") == 0) {
_lengthProperty = property;
}
}
for(int x = 0; x < type->getMethodCount(); x++) {
QSharedPointer<NetMethodInfo> method = type->getMethodInfo(x);
if(method->getMethodName().compare("Get") == 0) {
_getIndexed = method;
} else if(method->getMethodName().compare("Set") == 0) {
_setIndexed = method;
}
}
if(_lengthProperty == nullptr ||
_getIndexed == nullptr ||
_setIndexed == nullptr) {
_isIncomplete = true;
return;
}
}
bool NetTypeArrayFacade_Array::isIncomplete()
{
return _isIncomplete;
}
bool NetTypeArrayFacade_Array::isFixed()
{
// You can't change the size of an array.
return true;
}
uint NetTypeArrayFacade_Array::getLength(const QSharedPointer<NetReference>& reference)
{
QSharedPointer<NetVariant> result(new NetVariant());
QmlNet::readProperty(_lengthProperty, reference, nullptr, result);
return static_cast<uint>(result->getInt());
}
QSharedPointer<NetVariant> NetTypeArrayFacade_Array::getIndexed(const QSharedPointer<NetReference>& reference, uint index)
{
QSharedPointer<NetVariantList> parameters = QSharedPointer<NetVariantList>(new NetVariantList());
QSharedPointer<NetVariant> parameter = QSharedPointer<NetVariant>(new NetVariant());
parameter->setInt(static_cast<int>(index));
parameters->add(parameter);
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
QmlNet::invokeNetMethod(_getIndexed, reference, parameters, result);
return result;
}
void NetTypeArrayFacade_Array::setIndexed(const QSharedPointer<NetReference>& reference, uint index, const QSharedPointer<NetVariant>& value)
{
QSharedPointer<NetVariantList> parameters = QSharedPointer<NetVariantList>(new NetVariantList());
QSharedPointer<NetVariant> parameter = QSharedPointer<NetVariant>(new NetVariant());
parameter->setInt(static_cast<int>(index));
parameters->add(parameter);
parameters->add(value);
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
QmlNet::invokeNetMethod(_setIndexed, reference, parameters, result);
}

View file

@ -1,25 +0,0 @@
#ifndef NETTYPEARRAYFACADEARRAY_H
#define NETTYPEARRAYFACADEARRAY_H
#include <QmlNet/types/NetTypeArrayFacade.h>
class NetMethodInfo;
class NetPropertyInfo;
class NetTypeArrayFacade_Array : public NetTypeArrayFacade
{
public:
NetTypeArrayFacade_Array(const QSharedPointer<NetTypeInfo>& type);
bool isIncomplete();
bool isFixed() override;
uint getLength(const QSharedPointer<NetReference>& reference) override;
QSharedPointer<NetVariant> getIndexed(const QSharedPointer<NetReference>& reference, uint index) override;
void setIndexed(const QSharedPointer<NetReference>& reference, uint index, const QSharedPointer<NetVariant>& value) override;
private:
bool _isIncomplete;
QSharedPointer<NetPropertyInfo> _lengthProperty;
QSharedPointer<NetMethodInfo> _getIndexed;
QSharedPointer<NetMethodInfo> _setIndexed;
};
#endif // NETTYPEARRAYFACADEARRAY_H

View file

@ -1,94 +0,0 @@
#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(const 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;
}
}
for(int x = 0; x < type->getLocalMethodCount(); x++) {
QSharedPointer<NetMethodInfo> method = type->getLocalMethodInfo(x);
if(method->getMethodName().compare("RemoveAt") == 0) {
_removeAtMethod = method;
} else if(method->getMethodName().compare("Add") == 0) {
_addMethod = method;
}
}
if(_lengthProperty == nullptr ||
_itemProperty == nullptr ||
_removeAtMethod == nullptr ||
_addMethod == nullptr) {
_isIncomplete = true;
return;
}
}
bool NetTypeArrayFacade_List::isIncomplete()
{
return _isIncomplete;
}
bool NetTypeArrayFacade_List::isFixed()
{
return false;
}
uint NetTypeArrayFacade_List::getLength(const QSharedPointer<NetReference>& reference)
{
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
QmlNet::readProperty(_lengthProperty, reference, nullptr, result);
return static_cast<uint>(result->getInt());
}
QSharedPointer<NetVariant> NetTypeArrayFacade_List::getIndexed(const QSharedPointer<NetReference>& reference, uint index)
{
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
QSharedPointer<NetVariant> indexParameter = QSharedPointer<NetVariant>(new NetVariant());
indexParameter->setInt(qint32(index));
QmlNet::readProperty(_itemProperty, reference, indexParameter, result);
return result;
}
void NetTypeArrayFacade_List::setIndexed(const QSharedPointer<NetReference>& reference, uint index, const QSharedPointer<NetVariant>& value)
{
QSharedPointer<NetVariant> indexParameter = QSharedPointer<NetVariant>(new NetVariant());
indexParameter->setInt(qint32(index));
QmlNet::writeProperty(_itemProperty, reference, indexParameter, value);
}
void NetTypeArrayFacade_List::push(const QSharedPointer<NetReference>& reference, const QSharedPointer<NetVariant>& value)
{
QSharedPointer<NetVariantList> parameters = QSharedPointer<NetVariantList>(new NetVariantList());
parameters->add(value);
QmlNet::invokeNetMethod(_addMethod, reference, parameters, nullptr);
}
QSharedPointer<NetVariant> NetTypeArrayFacade_List::pop(const QSharedPointer<NetReference>& reference)
{
uint length = getLength(reference);
QSharedPointer<NetVariant> item = getIndexed(reference, length - 1);
deleteAt(reference, length - 1);
return item;
}
void NetTypeArrayFacade_List::deleteAt(const QSharedPointer<NetReference>& reference, uint index)
{
QSharedPointer<NetVariantList> parameters = QSharedPointer<NetVariantList>(new NetVariantList());
QSharedPointer<NetVariant> parameter = QSharedPointer<NetVariant>(new NetVariant());
parameter->setInt(static_cast<int>(index));
parameters->add(parameter);
QmlNet::invokeNetMethod(_removeAtMethod, reference, parameters, nullptr);
}

View file

@ -1,29 +0,0 @@
#ifndef NETTYPEARRAYFACADELIST_H
#define NETTYPEARRAYFACADELIST_H
#include <QmlNet/types/NetTypeArrayFacade.h>
class NetMethodInfo;
class NetPropertyInfo;
class NetTypeArrayFacade_List : public NetTypeArrayFacade
{
public:
NetTypeArrayFacade_List(const QSharedPointer<NetTypeInfo>& type);
bool isIncomplete();
bool isFixed() override;
uint getLength(const QSharedPointer<NetReference>& reference) override;
QSharedPointer<NetVariant> getIndexed(const QSharedPointer<NetReference>& reference, uint index) override;
void setIndexed(const QSharedPointer<NetReference>& reference, uint index, const QSharedPointer<NetVariant>& value) override;
void push(const QSharedPointer<NetReference>& reference, const QSharedPointer<NetVariant>& value) override;
QSharedPointer<NetVariant> pop(const QSharedPointer<NetReference>& reference) override;
void deleteAt(const QSharedPointer<NetReference>& reference, uint index) override;
private:
bool _isIncomplete;
QSharedPointer<NetPropertyInfo> _lengthProperty;
QSharedPointer<NetPropertyInfo> _itemProperty;
QSharedPointer<NetMethodInfo> _removeAtMethod;
QSharedPointer<NetMethodInfo> _addMethod;
};
#endif // NETTYPEARRAYFACADELIST_H

View file

@ -1,435 +0,0 @@
#include <QmlNet/types/NetTypeInfo.h>
#include <QmlNet/types/NetMethodInfo.h>
#include <QmlNet/types/NetPropertyInfo.h>
#include <QmlNet/types/NetSignalInfo.h>
#include <QmlNet/types/Callbacks.h>
#include <QmlNet/types/NetTypeArrayFacade.h>
#include <QmlNetUtilities.h>
#include <QMutex>
#include <utility>
using namespace QmlNet;
static int nextTypeId = 1;
Q_GLOBAL_STATIC(QMutex, typeIdMutex);
NetTypeInfo::NetTypeInfo(QString fullTypeName) :
metaObject(nullptr),
_fullTypeName(std::move(fullTypeName)),
_variantType(NetVariantTypeEnum_Invalid),
_isArray(false),
_isList(false),
_hasComponentCompleted(false),
_hasObjectDestroyed(false),
_arrayFacadeLoaded(false),
_lazyLoaded(false),
_isLoading(false)
{
typeIdMutex->lock();
_id = nextTypeId;
nextTypeId++;
typeIdMutex->unlock();
}
NetTypeInfo::~NetTypeInfo() = default;
int NetTypeInfo::getId()
{
return _id;
}
QString NetTypeInfo::getFullTypeName() {
return _fullTypeName;
}
QString NetTypeInfo::getBaseType() const
{
return _baseType;
}
void NetTypeInfo::setBaseType(const QString& baseType)
{
_baseType = baseType;
}
QString NetTypeInfo::getClassName() {
return _className;
}
void NetTypeInfo::setClassName(QString className) {
_className = std::move(className);
}
NetVariantTypeEnum NetTypeInfo::getPrefVariantType() {
return _variantType;
}
void NetTypeInfo::setPrefVariantType(NetVariantTypeEnum variantType) {
_variantType = variantType;
}
bool NetTypeInfo::isArray()
{
return _isArray;
}
void NetTypeInfo::setIsArray(bool isArray)
{
_isArray = isArray;
}
bool NetTypeInfo::isList()
{
return _isList;
}
void NetTypeInfo::setIsList(bool isList)
{
_isList = isList;
}
bool NetTypeInfo::hasComponentCompleted()
{
return _hasComponentCompleted;
}
void NetTypeInfo::setHasComponentCompleted(bool hasComponentCompleted)
{
_hasComponentCompleted = hasComponentCompleted;
}
bool NetTypeInfo::hasObjectDestroyed()
{
return _hasObjectDestroyed;
}
void NetTypeInfo::setHasObjectDestroyed(bool hasObjectDestroyed)
{
_hasObjectDestroyed = hasObjectDestroyed;
}
void NetTypeInfo::addMethod(const QSharedPointer<NetMethodInfo>& methodInfo) {
_methods.append(methodInfo);
if(methodInfo->isStatic()) {
_methodsStatic.append(methodInfo);
} else {
_methodsLocal.append(methodInfo);
}
}
int NetTypeInfo::getMethodCount() {
return _methods.size();
}
QSharedPointer<NetMethodInfo> NetTypeInfo::getMethodInfo(int index) {
if(index < 0) return QSharedPointer<NetMethodInfo>(nullptr);
if(index >= _methods.length()) return QSharedPointer<NetMethodInfo>(nullptr);
return _methods.at(index);
}
int NetTypeInfo::getLocalMethodCount()
{
return _methodsLocal.size();
}
QSharedPointer<NetMethodInfo> NetTypeInfo::getLocalMethodInfo(int index)
{
if(index < 0) return QSharedPointer<NetMethodInfo>(nullptr);
if(index >= _methodsLocal.length()) return QSharedPointer<NetMethodInfo>(nullptr);
return _methodsLocal.at(index);
}
int NetTypeInfo::getStaticMethodCount()
{
return _methodsStatic.size();
}
QSharedPointer<NetMethodInfo> NetTypeInfo::getStaticMethodInfo(int index)
{
if(index < 0) return QSharedPointer<NetMethodInfo>(nullptr);
if(index >= _methodsStatic.length()) return QSharedPointer<NetMethodInfo>(nullptr);
return _methodsStatic.at(index);
}
void NetTypeInfo::addProperty(const QSharedPointer<NetPropertyInfo>& property) {
_properties.append(property);
}
int NetTypeInfo::getPropertyCount() {
return _properties.size();
}
QSharedPointer<NetPropertyInfo> NetTypeInfo::getProperty(int index) {
if(index < 0) return QSharedPointer<NetPropertyInfo>(nullptr);
if(index >= _properties.length()) return QSharedPointer<NetPropertyInfo>(nullptr);
return _properties.at(index);
}
void NetTypeInfo::addSignal(const QSharedPointer<NetSignalInfo>& signal) {
_signals.append(signal);
}
int NetTypeInfo::getSignalCount() {
return _signals.size();
}
QSharedPointer<NetSignalInfo> NetTypeInfo::getSignal(int index) {
if(index < 0) return QSharedPointer<NetSignalInfo>(nullptr);
if(index >= _signals.size()) return QSharedPointer<NetSignalInfo>(nullptr);
return _signals.at(index);
}
QSharedPointer<NetTypeArrayFacade> NetTypeInfo::getArrayFacade()
{
if(_arrayFacadeLoaded) {
return _arrayFacade;
}
ensureLoaded();
_arrayFacade = NetTypeArrayFacade::fromType(sharedFromThis());
_arrayFacadeLoaded = true;
return _arrayFacade;
}
bool NetTypeInfo::isLoaded() {
return _lazyLoaded;
}
bool NetTypeInfo::isLoading() {
return _isLoading;
}
void NetTypeInfo::ensureLoaded() {
if (_lazyLoaded) {
return;
}
if(_isLoading) {
// Prevent recursion
qFatal("Recursion detected on type loading for type: %s", qPrintable(getFullTypeName()));
}
_isLoading = true;
loadTypeInfo(sharedFromThis());
_isLoading = false;
_lazyLoaded = true;
}
extern "C" {
static_assert (std::is_pointer<LPWSTR>::value, "Check fromUtf16 calls below.");
static_assert (!std::is_pointer<std::remove_pointer<LPWSTR>::type>::value, "Check fromUtf16 calls below.");
static_assert (sizeof(std::remove_pointer<LPWSTR>::type) == sizeof(ushort), "Check fromUtf16 calls below.");
Q_DECL_EXPORT NetTypeInfoContainer* type_info_create(LPWSTR fullTypeName) {
NetTypeInfoContainer* result = new NetTypeInfoContainer();
result->netTypeInfo = QSharedPointer<NetTypeInfo>(new NetTypeInfo(QString::fromUtf16(static_cast<const char16_t*>(fullTypeName))));
return result;
}
Q_DECL_EXPORT void type_info_destroy(NetTypeInfoContainer* netTypeInfo) {
delete netTypeInfo;
netTypeInfo = nullptr;
}
Q_DECL_EXPORT int type_info_getId(NetTypeInfoContainer* netTypeInfo)
{
return netTypeInfo->netTypeInfo->getId();
}
Q_DECL_EXPORT QmlNetStringContainer* type_info_getFullTypeName(NetTypeInfoContainer* netTypeInfo) {
QString result = netTypeInfo->netTypeInfo->getFullTypeName();
return createString(result);
}
Q_DECL_EXPORT QmlNetStringContainer* type_info_getBaseType(NetTypeInfoContainer* netTypeInfo)
{
auto result = netTypeInfo->netTypeInfo->getBaseType();
return createString(result);
}
Q_DECL_EXPORT void type_info_setBaseType(NetTypeInfoContainer* netTypeInfo, LPWCSTR baseType)
{
if(baseType == nullptr) {
netTypeInfo->netTypeInfo->setBaseType(QString());
} else {
netTypeInfo->netTypeInfo->setBaseType(QString::fromUtf16(baseType));
}
}
Q_DECL_EXPORT QmlNetStringContainer* type_info_getClassName(NetTypeInfoContainer* netTypeInfo) {
QString result = netTypeInfo->netTypeInfo->getClassName();
return createString(result);
}
Q_DECL_EXPORT void type_info_setClassName(NetTypeInfoContainer* netTypeInfo, LPWSTR className) {
netTypeInfo->netTypeInfo->setClassName(QString::fromUtf16(static_cast<const char16_t*>(className)));
}
Q_DECL_EXPORT NetVariantTypeEnum type_info_getPrefVariantType(NetTypeInfoContainer* netTypeInfo) {
return netTypeInfo->netTypeInfo->getPrefVariantType();
}
Q_DECL_EXPORT void type_info_setPrefVariantType(NetTypeInfoContainer* netTypeInfo, NetVariantTypeEnum variantType) {
netTypeInfo->netTypeInfo->setPrefVariantType(variantType);
}
Q_DECL_EXPORT uchar type_info_getIsArray(NetTypeInfoContainer* netTypeInfo)
{
if(netTypeInfo->netTypeInfo->isArray()) {
return 1;
} else {
return 0;
}
}
Q_DECL_EXPORT void type_info_setIsArray(NetTypeInfoContainer* netTypeInfo, uchar isArray)
{
netTypeInfo->netTypeInfo->setIsArray(isArray == 1);
}
Q_DECL_EXPORT uchar type_info_getIsList(NetTypeInfoContainer* netTypeInfo)
{
if(netTypeInfo->netTypeInfo->isList()) {
return 1;
} else {
return 0;
}
}
Q_DECL_EXPORT void type_info_setIsList(NetTypeInfoContainer* netTypeInfo, uchar isList)
{
netTypeInfo->netTypeInfo->setIsList(isList == 1);
}
Q_DECL_EXPORT uchar type_info_getHasComponentCompleted(NetTypeInfoContainer* netTypeInfo)
{
if(netTypeInfo->netTypeInfo->hasComponentCompleted()) {
return 1;
} else {
return 0;
}
}
Q_DECL_EXPORT void type_info_setHasComponentCompleted(NetTypeInfoContainer* netTypeInfo, uchar hasComponentCompleted)
{
netTypeInfo->netTypeInfo->setHasComponentCompleted(hasComponentCompleted == 1);
}
Q_DECL_EXPORT uchar type_info_getHasObjectDestroyed(NetTypeInfoContainer* netTypeInfo)
{
if(netTypeInfo->netTypeInfo->hasObjectDestroyed()) {
return 1;
} else {
return 0;
}
}
Q_DECL_EXPORT void type_info_setHasObjectDestroyed(NetTypeInfoContainer* netTypeInfo, uchar hasObjectDestroyed)
{
netTypeInfo->netTypeInfo->setHasObjectDestroyed(hasObjectDestroyed == 1);
}
Q_DECL_EXPORT void type_info_addMethod(NetTypeInfoContainer* netTypeInfo, NetMethodInfoContainer* methodInfo) {
netTypeInfo->netTypeInfo->addMethod(methodInfo->method);
}
Q_DECL_EXPORT int type_info_getMethodCount(NetTypeInfoContainer* container) {
return container->netTypeInfo->getMethodCount();
}
Q_DECL_EXPORT NetMethodInfoContainer* type_info_getMethodInfo(NetTypeInfoContainer* container, int index) {
QSharedPointer<NetMethodInfo> methodInfo = container->netTypeInfo->getMethodInfo(index);
if(methodInfo == nullptr) {
return nullptr;
}
NetMethodInfoContainer* result = new NetMethodInfoContainer();
result->method = methodInfo;
return result;
}
Q_DECL_EXPORT int type_info_getLocalMethodCount(NetTypeInfoContainer* container)
{
return container->netTypeInfo->getLocalMethodCount();
}
Q_DECL_EXPORT NetMethodInfoContainer* type_info_getLocalMethodInfo(NetTypeInfoContainer* container, int index) {
QSharedPointer<NetMethodInfo> methodInfo = container->netTypeInfo->getLocalMethodInfo(index);
if(methodInfo == nullptr) {
return nullptr;
}
NetMethodInfoContainer* result = new NetMethodInfoContainer();
result->method = methodInfo;
return result;
}
Q_DECL_EXPORT int type_info_getStaticMethodCount(NetTypeInfoContainer* container)
{
return container->netTypeInfo->getStaticMethodCount();
}
Q_DECL_EXPORT NetMethodInfoContainer* type_info_getStaticMethodInfo(NetTypeInfoContainer* container, int index) {
QSharedPointer<NetMethodInfo> methodInfo = container->netTypeInfo->getStaticMethodInfo(index);
if(methodInfo == nullptr) {
return nullptr;
}
NetMethodInfoContainer* result = new NetMethodInfoContainer();
result->method = methodInfo;
return result;
}
Q_DECL_EXPORT void type_info_addProperty(NetTypeInfoContainer* container, NetPropertyInfoContainer* propertyContainer) {
container->netTypeInfo->addProperty(propertyContainer->property);
}
Q_DECL_EXPORT int type_info_getPropertyCount(NetTypeInfoContainer* container) {
return container->netTypeInfo->getPropertyCount();
}
Q_DECL_EXPORT NetPropertyInfoContainer* type_info_getProperty(NetTypeInfoContainer* container, int index) {
QSharedPointer<NetPropertyInfo> property = container->netTypeInfo->getProperty(index);
if(property == nullptr) {
return nullptr;
}
NetPropertyInfoContainer* result = new NetPropertyInfoContainer();
result->property = property;
return result;
}
Q_DECL_EXPORT void type_info_addSignal(NetTypeInfoContainer* container, NetSignalInfoContainer* signalContainer) {
container->netTypeInfo->addSignal(signalContainer->signal);
}
Q_DECL_EXPORT int type_info_getSignalCount(NetTypeInfoContainer* container) {
return container->netTypeInfo->getSignalCount();
}
Q_DECL_EXPORT NetSignalInfoContainer* type_info_getSignal(NetTypeInfoContainer* container, int index) {
QSharedPointer<NetSignalInfo> signal = container->netTypeInfo->getSignal(index);
if(signal == nullptr) {
return nullptr;
}
NetSignalInfoContainer* result = new NetSignalInfoContainer();
result->signal = signal;
return result;
}
Q_DECL_EXPORT uchar type_info_isLoaded(NetTypeInfoContainer* container) {
if(container->netTypeInfo->isLoaded()) {
return 1;
} else {
return 0;
}
}
Q_DECL_EXPORT uchar type_info_isLoading(NetTypeInfoContainer* container) {
if(container->netTypeInfo->isLoading()) {
return 1;
} else {
return 0;
}
}
Q_DECL_EXPORT void type_info_ensureLoaded(NetTypeInfoContainer* container) {
container->netTypeInfo->ensureLoaded();
}
}

View file

@ -1,96 +0,0 @@
#ifndef NET_TYPE_INFO_H
#define NET_TYPE_INFO_H
#include <QmlNet.h>
#include <QList>
#include <QString>
#include <QSharedPointer>
#include <QEnableSharedFromThis>
class NetMethodInfo;
class NetPropertyInfo;
class NetSignalInfo;
class NetTypeArrayFacade;
class NetTypeInfo : public QEnableSharedFromThis<NetTypeInfo> {
public:
NetTypeInfo(QString fullTypeName);
~NetTypeInfo();
int getId();
QString getFullTypeName();
QString getBaseType() const;
void setBaseType(const QString& baseType);
QString getClassName();
void setClassName(QString className);
NetVariantTypeEnum getPrefVariantType();
void setPrefVariantType(NetVariantTypeEnum variantType);
bool isArray();
void setIsArray(bool isArray);
bool isList();
void setIsList(bool isList);
bool hasComponentCompleted();
void setHasComponentCompleted(bool hasComponentCompleted);
bool hasObjectDestroyed();
void setHasObjectDestroyed(bool hasObjectDestroyed);
void addMethod(const QSharedPointer<NetMethodInfo>& methodInfo);
int getMethodCount();
QSharedPointer<NetMethodInfo> getMethodInfo(int index);
int getLocalMethodCount();
QSharedPointer<NetMethodInfo> getLocalMethodInfo(int index);
int getStaticMethodCount();
QSharedPointer<NetMethodInfo> getStaticMethodInfo(int index);
void addProperty(const QSharedPointer<NetPropertyInfo>& property);
int getPropertyCount();
QSharedPointer<NetPropertyInfo> getProperty(int index);
void addSignal(const QSharedPointer<NetSignalInfo>& signal);
int getSignalCount();
QSharedPointer<NetSignalInfo> getSignal(int index);
QSharedPointer<NetTypeArrayFacade> getArrayFacade();
bool isLoaded();
bool isLoading();
void ensureLoaded();
QMetaObject* metaObject;
private:
int _id;
QString _fullTypeName;
QString _baseType;
QString _className;
NetVariantTypeEnum _variantType;
bool _isArray;
bool _isList;
bool _hasComponentCompleted;
bool _hasObjectDestroyed;
QList<QSharedPointer<NetMethodInfo>> _methods;
QList<QSharedPointer<NetMethodInfo>> _methodsLocal;
QList<QSharedPointer<NetMethodInfo>> _methodsStatic;
QList<QSharedPointer<NetPropertyInfo>> _properties;
QList<QSharedPointer<NetSignalInfo>> _signals;
QSharedPointer<NetTypeArrayFacade> _arrayFacade;
bool _arrayFacadeLoaded;
bool _lazyLoaded;
bool _isLoading;
};
struct Q_DECL_EXPORT NetTypeInfoContainer {
QSharedPointer<NetTypeInfo> netTypeInfo;
};
#endif // NET_TYPE_INFO_H

View file

@ -1,50 +0,0 @@
#include <QmlNet/types/NetTypeManager.h>
#include <QmlNet/types/Callbacks.h>
#include <QSharedPointer>
#include <QDebug>
using namespace QmlNet;
QMap<QString, QSharedPointer<NetTypeInfo>> NetTypeManager::types;
NetTypeManager::NetTypeManager() = default;
QSharedPointer<NetTypeInfo> NetTypeManager::getTypeInfo(const QString& typeName) {
if(NetTypeManager::types.contains(typeName))
return NetTypeManager::types.value(typeName);
if(!isTypeValid(typeName)) {
qWarning() << "Invalid type name:" << typeName;
return QSharedPointer<NetTypeInfo>();
}
QSharedPointer<NetTypeInfo> typeInfo(new NetTypeInfo(typeName));
NetTypeManager::types.insert(typeName, typeInfo);
createLazyTypeInfo(typeInfo);
return typeInfo;
}
QSharedPointer<NetTypeInfo> NetTypeManager::getBaseType(QSharedPointer<NetTypeInfo> typeInfo)
{
auto baseType = typeInfo->getBaseType();
if(baseType.isNull() || baseType.isEmpty()) {
return nullptr;
}
return NetTypeManager::getTypeInfo(baseType);
}
extern "C" {
Q_DECL_EXPORT NetTypeInfoContainer* type_manager_getTypeInfo(LPWSTR fullTypeName) {
QSharedPointer<NetTypeInfo> typeInfo = NetTypeManager::getTypeInfo(QString::fromUtf16(static_cast<const char16_t*>(fullTypeName)));
if(typeInfo == nullptr) {
return nullptr;
}
NetTypeInfoContainer* container = new NetTypeInfoContainer();
container->netTypeInfo = typeInfo;
return container;
}
}

View file

@ -1,19 +0,0 @@
#ifndef NETTYPEMANAGER_H
#define NETTYPEMANAGER_H
#include <QmlNet.h>
#include <QSharedPointer>
class NetTypeInfo;
class NetTypeManager {
public:
NetTypeManager();
static QSharedPointer<NetTypeInfo> getTypeInfo(const QString& typeName);
static QSharedPointer<NetTypeInfo> getBaseType(QSharedPointer<NetTypeInfo> typeInfo);
private:
static QMap<QString, QSharedPointer<NetTypeInfo>> types;
};
#endif // NETTYPEMANAGER_H

View file

@ -1,25 +0,0 @@
SOURCES += \
$$PWD/NetTypeInfo.cpp \
$$PWD/NetTypeManager.cpp \
$$PWD/Callbacks.cpp \
$$PWD/NetMethodInfo.cpp \
$$PWD/NetPropertyInfo.cpp \
$$PWD/NetReference.cpp \
$$PWD/NetSignalInfo.cpp \
$$PWD/NetDelegate.cpp \
$$PWD/NetTypeArrayFacade.cpp \
$$PWD/NetTypeArrayFacadeArray.cpp \
$$PWD/NetTypeArrayFacadeList.cpp
HEADERS += \
$$PWD/NetTypeInfo.h \
$$PWD/NetTypeManager.h \
$$PWD/Callbacks.h \
$$PWD/NetMethodInfo.h \
$$PWD/NetPropertyInfo.h \
$$PWD/NetReference.h \
$$PWD/NetSignalInfo.h \
$$PWD/NetDelegate.h \
$$PWD/NetTypeArrayFacade.h \
$$PWD/NetTypeArrayFacadeArray.h \
$$PWD/NetTypeArrayFacadeList.h

View file

@ -1,29 +0,0 @@
#include <QmlNetUtilities.h>
extern "C" {
QmlNetStringContainer* createString(const QString& value)
{
if(value.isNull()) {
return nullptr;
}
QmlNetStringContainer* result = new QmlNetStringContainer();
result->container = new QString(value);
result->data = result->container->utf16();
return result;
}
void freeString(QmlNetStringContainer* container)
{
if(container) {
delete container->container;
delete container;
}
}
}

View file

@ -1,19 +0,0 @@
#ifndef QMLNETUTILITIES_H
#define QMLNETUTILITIES_H
#include <QmlNet.h>
#include <QString>
struct QmlNetStringContainer {
QString* container;
const ushort* data;
};
extern "C" {
Q_DECL_EXPORT QmlNetStringContainer* createString(const QString& value);
Q_DECL_EXPORT void freeString(QmlNetStringContainer* container);
}
#endif // QMLNETUTILITIES_H

View file

@ -6,7 +6,7 @@ namespace Qml.Net.Benchmarks
{
static void Main(string[] args)
{
BenchmarkRunner.Run<ReferenceBenchmarks>();
BenchmarkRunner.Run<QObjectMethodBenchmarks>();
}
}
}

View file

@ -0,0 +1,49 @@
using BenchmarkDotNet.Attributes;
using Qml.Net.Internal.Qml;
namespace Qml.Net.Benchmarks
{
[Config(typeof(Config))]
public class QObjectMethodBenchmarks
{
private static QGuiApplication _guiApplication;
private static QQmlApplicationEngine _qmlApplicationEngine;
private static INetQObject _qObject;
[GlobalSetup]
public void GlobalSetup()
{
_guiApplication = new QGuiApplication(new[] { "-platform", "offscreen" });
_qmlApplicationEngine = new QQmlApplicationEngine();
NetTestHelper.RunQml(
_qmlApplicationEngine,
@"
import QtQuick 2.0
import tests 1.0
Item {{
}}");
_qObject = Qt.BuildQObject("TestQObject*");
}
[GlobalCleanup]
public void GlobalCleanup()
{
_qObject.Dispose();
QCoreApplication.ProcessEvents(QEventLoop.ProcessEventsFlag.AllEvents);
_qmlApplicationEngine.Dispose();
_guiApplication.Dispose();
}
[Benchmark]
public void TestSlotInt()
{
_qObject.InvokeMethod("testSlotInt", 3);
}
[Benchmark]
public void TestSlotQObject()
{
_qObject.InvokeMethod("testSlotQObject", _qObject);
}
}
}

View file

@ -1,92 +0,0 @@
using BenchmarkDotNet.Attributes;
namespace Qml.Net.Benchmarks
{
[Config(typeof(Config))]
public class ReferenceBenchmarks
{
private static QGuiApplication _guiApplication;
private static QQmlApplicationEngine _qmlApplicationEngine;
private static bool _initialized;
[GlobalSetup]
public void GlobalSetup()
{
if (!_initialized)
{
Qml.RegisterType<QmlType>("tests");
_initialized = true;
}
}
[IterationSetup]
public void Setup()
{
_guiApplication = new QGuiApplication(new[] { "-platform", "offscreen" });
_qmlApplicationEngine = new QQmlApplicationEngine();
}
[IterationCleanup]
public void Cleanup()
{
_qmlApplicationEngine.Dispose();
_guiApplication.Dispose();
}
[Benchmark]
public void Run()
{
_qmlApplicationEngine.LoadData(@"
import QtQuick 2.0
import tests 1.0
Item {
property int count: 0
Timer {
interval: 1
running: true
repeat: true
onTriggered: {
var o1 = test.GetObject()
var o2 = test.GetObject()
var o3 = test.GetObject()
var o4 = test.GetObject()
var i;
for (i = 0; i < 500; i++) {
var t = test.GetObject()
}
count++
if(count == 100) {
test.TestFinished()
}
}
}
QmlType {
id: test
}
}
");
_guiApplication.Exec();
}
public class QmlType
{
private readonly InnerType _object = new InnerType();
public object GetObject()
{
return _object;
}
public void TestFinished()
{
QCoreApplication.Exit();
}
public class InnerType
{
}
}
}
}

View file

@ -134,7 +134,7 @@ namespace Qml.Net.Tests.CodeGen
});
TestGet(x => x.BoolNullable, null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
TestSet(x => x.Bool, NetVariant.From(true), x => x.Bool = true);
@ -157,7 +157,7 @@ namespace Qml.Net.Tests.CodeGen
});
TestGet(x => x.CharNullable, (char?)null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
TestSet(x => x.Char, NetVariant.From('C'), x => x.Char = 'C');
@ -180,7 +180,7 @@ namespace Qml.Net.Tests.CodeGen
});
TestGet(x => x.IntNullable, (char?)null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
TestSet(x => x.Int, NetVariant.From(20), x => x.Int = 20);
@ -203,7 +203,7 @@ namespace Qml.Net.Tests.CodeGen
});
TestGet(x => x.UIntNullable, null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
TestSet(x => x.UInt, NetVariant.From(20), x => x.UInt = 20);
@ -226,7 +226,7 @@ namespace Qml.Net.Tests.CodeGen
});
TestGet(x => x.LongNullable, null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
TestSet(x => x.Long, NetVariant.From((long)20), x => x.Long = 20);
@ -249,7 +249,7 @@ namespace Qml.Net.Tests.CodeGen
});
TestGet(x => x.ULongNullable, null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
TestSet(x => x.ULong, NetVariant.From((ulong)20), x => x.ULong = 20);
@ -272,7 +272,7 @@ namespace Qml.Net.Tests.CodeGen
});
TestGet(x => x.FloatNullable, null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
TestSet(x => x.Float, NetVariant.From((float)20), x => x.Float = 20);
@ -295,7 +295,7 @@ namespace Qml.Net.Tests.CodeGen
});
TestGet(x => x.DoubleNullable, null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
TestSet(x => x.Double, NetVariant.From((double)20), x => x.Double = 20);
@ -318,7 +318,7 @@ namespace Qml.Net.Tests.CodeGen
});
TestGet(x => x.String, null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
TestSet(x => x.String, NetVariant.From(""), x => x.String = "");
@ -344,7 +344,7 @@ namespace Qml.Net.Tests.CodeGen
});
TestGet(x => x.DateTimeNullable, null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
TestSet(x => x.DateTime, NetVariant.From(time), x => x.DateTime = time);
@ -364,7 +364,7 @@ namespace Qml.Net.Tests.CodeGen
});
TestGet(x => x.Obj, null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
TestSet(x => x.Obj, NetVariant.From((object)null), x => x.Obj = null);
@ -382,7 +382,7 @@ namespace Qml.Net.Tests.CodeGen
});
TestGet(x => x.ObjTyped, null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
TestSet(x => x.ObjTyped, NetVariant.From((RandomType)null), x => x.ObjTyped = null);
@ -406,7 +406,7 @@ namespace Qml.Net.Tests.CodeGen
});
TestGet(x => x.StructNullable, null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
TestSet(x => x.Struct, NetVariant.From(o), x => x.Struct = o);
@ -429,7 +429,7 @@ namespace Qml.Net.Tests.CodeGen
});
TestGet(x => x.EnumNullable, null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
TestSet(x => x.Enum, NetVariant.From(RandomEnum.Value2), x => x.Enum = RandomEnum.Value2);

View file

@ -160,7 +160,7 @@ namespace Qml.Net.Tests.CodeGen
});
Test(x => x.ReturnTypeBoolNullable(), null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
}
@ -179,7 +179,7 @@ namespace Qml.Net.Tests.CodeGen
});
Test(x => x.ReturnTypeCharNullable(), null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
}
@ -198,7 +198,7 @@ namespace Qml.Net.Tests.CodeGen
});
Test(x => x.ReturnTypeIntNullable(), null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
}
@ -217,7 +217,7 @@ namespace Qml.Net.Tests.CodeGen
});
Test(x => x.ReturnTypeUIntNullable(), null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
}
@ -236,7 +236,7 @@ namespace Qml.Net.Tests.CodeGen
});
Test(x => x.ReturnTypeLongNullable(), null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
}
@ -255,7 +255,7 @@ namespace Qml.Net.Tests.CodeGen
});
Test(x => x.ReturnTypeULongNullable(), null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
}
@ -274,7 +274,7 @@ namespace Qml.Net.Tests.CodeGen
});
Test(x => x.ReturnTypeFloatNullable(), null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
}
@ -293,7 +293,7 @@ namespace Qml.Net.Tests.CodeGen
});
Test(x => x.ReturnTypeDoubleNullable(), null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
}
@ -312,7 +312,7 @@ namespace Qml.Net.Tests.CodeGen
});
Test(x => x.ReturnTypeString(), null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
}
@ -333,7 +333,7 @@ namespace Qml.Net.Tests.CodeGen
});
Test(x => x.ReturnTypeDateTimeNullable(), null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
}
@ -348,7 +348,7 @@ namespace Qml.Net.Tests.CodeGen
});
Test(x => x.ReturnTypeObject(), null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
}
@ -363,7 +363,7 @@ namespace Qml.Net.Tests.CodeGen
});
Test(x => x.ReturnTypeObjectTyped(), null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
}
@ -383,7 +383,7 @@ namespace Qml.Net.Tests.CodeGen
});
Test(x => x.ReturnTypeStructNullable(), null, result =>
{
result.VariantType.Should().Be(NetVariantType.Invalid);
result.VariantType.Should().Be(NetVariantType.Null);
});
}

View file

@ -0,0 +1,46 @@
using System;
using System.Threading.Tasks;
using FluentAssertions;
using Qml.Net.Internal.Qml;
using Qml.Net.Internal.Types;
using Qml.Net.Tests.Types;
using Xunit;
namespace Qml.Net.Tests.CodeGen
{
public class CodeGenStructTests
{
public struct TestObject
{
public string TestProperty { get; set; }
}
[Fact]
public void Can_get_property()
{
try
{
var value = new TestObject();
value.TestProperty = "value1";
var typeInfo = NetTypeManager.GetTypeInfo<TestObject>();
typeInfo.EnsureLoaded();
var readProperty =
global::Qml.Net.Internal.CodeGen.CodeGen.BuildReadPropertyDelegate(typeInfo.GetProperty(0));
NetVariant result = new NetVariant();
Task taskResult = null;
readProperty(NetReference.CreateForObject(value), new NetVariantList(), result, ref taskResult);
result.String.Should().Be("value1");
throw new Exception("This shouldn't be ran");
}
catch (Exception ex)
{
ex.Message.Should().StartWith("Can't operate on struct types yet");
}
}
}
}

View file

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFrameworks>netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>

View file

@ -9,16 +9,6 @@ using Qml.Net.Internal.Qml;
namespace Qml.Net.Tests.Qml
{
public class TestContext
{
public void Quit()
{
Quited = true;
}
public bool Quited { get; set; }
}
public abstract class AbstractBaseQmlTests<TTypeToRegister> : BaseTests
{
private readonly QGuiApplication _coreApplication;
@ -27,7 +17,6 @@ namespace Qml.Net.Tests.Qml
protected MockTypeCreator TypeCreator { get; private set; }
readonly List<Type> _registeredTypes = new List<Type>();
static bool _testContextRegistered = false;
protected AbstractBaseQmlTests()
{
@ -35,12 +24,6 @@ namespace Qml.Net.Tests.Qml
qmlApplicationEngine = new QQmlApplicationEngine();
TypeCreator = new MockTypeCreator();
Net.TypeCreator.Current = TypeCreator;
TypeCreator.SetInstance(typeof(TestContext), new TestContext());
if (!_testContextRegistered)
{
Net.Qml.RegisterType<TestContext>("testContext");
_testContextRegistered = true;
}
}
protected virtual void RegisterType<T>()
@ -50,15 +33,9 @@ namespace Qml.Net.Tests.Qml
Net.Qml.RegisterType<T>("tests");
}
protected bool ExecApplicationWithTimeout(int timeoutMs)
protected void RunQmlTest(string instanceId, string componentOnCompletedCode, bool runEvents = false, bool failOnQmlWarnings = true)
{
var testContext = TypeCreator.Create(typeof(TestContext)) as TestContext;
return QTest.QWaitFor(() => testContext.Quited, timeoutMs);
}
protected void RunQmlTest(string instanceId, string componentOnCompletedCode)
{
NetTestHelper.RunQml(
var result = NetTestHelper.RunQml(
qmlApplicationEngine,
string.Format(
@"
@ -71,10 +48,16 @@ namespace Qml.Net.Tests.Qml
{2}
}}
}}
",
typeof(TTypeToRegister).Name,
instanceId,
componentOnCompletedCode));
",
typeof(TTypeToRegister).Name,
instanceId,
componentOnCompletedCode),
runEvents,
failOnQmlWarnings);
if (result == false)
{
throw new Exception($"Couldn't execute qml: {componentOnCompletedCode}");
}
}
public override void Dispose()

View file

@ -0,0 +1,59 @@
using System.Runtime.CompilerServices;
using Moq;
using Xunit;
namespace Qml.Net.Tests.Qml
{
public class ByteArrayTests : BaseQmlTests<ByteArrayTests.ByteArrayTestsQml>
{
public class ByteArrayTestsQml
{
public virtual byte[] Array { get; set; }
}
[Fact]
public void Can_get_and_set_byte_array()
{
Mock.SetupGet(x => x.Array).Returns(new byte[] { 3, 5 });
RunQmlTest(
"test",
@"
var v = test.array
var data = new Uint8Array(v)
data.set([4], 0)
test.array = v
");
Mock.VerifyGet(x => x.Array, Times.Once);
Mock.VerifySet(x => x.Array = new byte[]{4,5});
}
[Fact]
public void Can_get_and_set_byte_array_with_null()
{
Mock.SetupGet(x => x.Array).Returns((byte[])null);
RunQmlTest(
"test",
@"
test.array = test.array
");
Mock.VerifyGet(x => x.Array, Times.Once);
Mock.VerifySet(x => x.Array = null);
}
[Fact]
public void Can_set_byte_array_null()
{
RunQmlTest(
"test",
@"
test.array = null
");
Mock.VerifySet(x => x.Array = null);
}
}
}

View file

@ -0,0 +1,124 @@
using System;
using System.Drawing;
using FluentAssertions;
using Moq;
using Xunit;
namespace Qml.Net.Tests.Qml
{
public class ColorTests : BaseQmlTests<ColorTests.ColorTestsQml>
{
public class ColorTestsQml
{
public Color Value { get; set; }
public Color NullColor => Color.Empty;
public bool CheckResult { get; set; }
public int A { get; set; }
public int R { get; set; }
public int G { get; set; }
public int B { get; set; }
}
[Fact]
public void Converts_empty_dotnet_color_to_null()
{
RunQmlTest(
"test",
@"
test.checkResult = test.nullColor === null;
");
Mock.Object.CheckResult.Should().BeTrue();
}
[Fact]
public void Converts_null_to_empty_dotnet_color()
{
Mock.Object.Value = Color.Red;
RunQmlTest(
"test",
@"
test.value = null;
");
Mock.Object.Value.Should().Be(Color.Empty);
}
[Fact]
public void Converts_predefined_colors_to_rgba()
{
Mock.Object.Value = Color.MediumAquamarine;
RunQmlTest(
"test",
@"
const {a, r, g, b} = test.value;
test.a = a * 255;
test.r = r * 255;
test.g = g * 255;
test.b = b * 255;
");
Mock.Object.A.Should().Be(Color.MediumAquamarine.A);
Mock.Object.R.Should().Be(Color.MediumAquamarine.R);
Mock.Object.G.Should().Be(Color.MediumAquamarine.G);
Mock.Object.B.Should().Be(Color.MediumAquamarine.B);
}
[Fact]
public void Converts_custom_colors_to_rgba()
{
Mock.Object.Value = Color.FromArgb(100, 150, 200, 250);
RunQmlTest(
"test",
@"
const {a, r, g, b} = test.value;
test.a = a * 255;
test.r = r * 255;
test.g = g * 255;
test.b = b * 255;
");
Mock.Object.A.Should().Be(100);
Mock.Object.R.Should().Be(150);
Mock.Object.G.Should().Be(200);
Mock.Object.B.Should().Be(250);
}
[Fact]
public void Converted_color_is_comparable_to_Qt_color()
{
Mock.Object.Value = Color.FromArgb(100, 150, 200, 250);
RunQmlTest(
"test",
@"
if (test.value !== Qt.rgba(150 / 255, 200 / 255, 250 / 255, 100 / 255)) {
throw new Error('Converted color should be comparable to color, but got: ' + test.value);
}
");
}
[Fact]
public void Converts_qml_color_to_dotnet_color()
{
Mock.Object.Value = Color.Empty;
RunQmlTest(
"test",
@"
test.value = Qt.rgba(150 / 255.0, 200 / 255.0, 250 / 255.0, 100 / 255.0);
");
Mock.Object.Value.Should().Be(Color.FromArgb(100, 150, 200, 250));
}
}
}

View file

@ -116,7 +116,7 @@ namespace Qml.Net.Tests.Qml
}
[Fact]
public void Nullable_enum_is_null_type_is_js_when_null()
public void Nullable_enum_is_null_type_in_js_when_null()
{
Mock.Setup(x => x.ValueNullable).Returns((EnumTestsObject.TestEnum?)null);
Mock.Setup(x => x.Test(It.IsAny<string>()));

Some files were not shown because too many files have changed in this diff Show more