@nativescript/windows 0.1.0-alpha.8 → 0.1.0-alpha.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build.ps1 +44 -2
- package/framework/__PROJECT_NAME__/App.xaml.cs +67 -22
- package/framework/__PROJECT_NAME__/Assets/SplashScreen.png +0 -0
- package/framework/__PROJECT_NAME__/Assets/Square150x150Logo.png +0 -0
- package/framework/__PROJECT_NAME__/Assets/Square44x44Logo.png +0 -0
- package/framework/__PROJECT_NAME__/Assets/StoreLogo.png +0 -0
- package/framework/__PROJECT_NAME__/Assets/Wide310x150Logo.png +0 -0
- package/framework/__PROJECT_NAME__/CrashDiagnostics.cs +262 -66
- package/framework/__PROJECT_NAME__/Directory.Build.props +15 -0
- package/framework/__PROJECT_NAME__/Directory.Build.targets +153 -0
- package/framework/__PROJECT_NAME__/Package.appxmanifest +2 -5
- package/framework/__PROJECT_NAME__/RuntimeHost.cs +97 -10
- package/framework/__PROJECT_NAME__/__PROJECT_NAME__.csproj +85 -12
- package/framework/dotnet-bridge/BinaryProtocol.cs +145 -0
- package/framework/dotnet-bridge/Bridge.BinaryDispatch.cs +216 -0
- package/framework/dotnet-bridge/Bridge.Dispatch.cs +468 -0
- package/framework/dotnet-bridge/Bridge.JsDelegate.cs +96 -0
- package/framework/dotnet-bridge/Bridge.TaskHelper.cs +207 -0
- package/framework/dotnet-bridge/Bridge.cs +402 -263
- package/framework/dotnet-bridge/DispatchTypes.cs +317 -0
- package/framework/dotnet-bridge/DotNetBridge.csproj +7 -1
- package/framework/libs/arm64/nativescript.dll +0 -0
- package/framework/libs/devtools/arm64/nativescript.dll +0 -0
- package/framework/libs/devtools/x64/nativescript.dll +0 -0
- package/framework/libs/x64/nativescript.dll +0 -0
- package/framework/tools/dotnet-tool-arm64.exe +0 -0
- package/framework/tools/dotnet-tool-x64.exe +0 -0
- package/framework/tools/dotnet-tool.exe +0 -0
- package/package.json +19 -19
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Buffers;
|
|
3
|
+
using System.Collections;
|
|
4
|
+
using System.Collections.Concurrent;
|
|
5
|
+
using System.Collections.Generic;
|
|
6
|
+
using System.Linq.Expressions;
|
|
7
|
+
using System.Reflection;
|
|
8
|
+
using System.Text.Json;
|
|
9
|
+
using System.Text.Json.Serialization;
|
|
10
|
+
using System.Threading;
|
|
11
|
+
using System.Threading.Tasks;
|
|
12
|
+
|
|
13
|
+
namespace NativeScriptBridge;
|
|
14
|
+
|
|
15
|
+
[JsonSerializable(typeof(InvokeRequest))]
|
|
16
|
+
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
|
|
17
|
+
internal partial class BridgeJsonContext : JsonSerializerContext { }
|
|
18
|
+
|
|
19
|
+
internal sealed record InvokeRequest(
|
|
20
|
+
string? Assembly,
|
|
21
|
+
string? TypeName,
|
|
22
|
+
string? Method,
|
|
23
|
+
int? Handle,
|
|
24
|
+
JsonElement[]? Args
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
//
|
|
28
|
+
// Using Type as the key field (rather than Type.FullName) is correct and faster:
|
|
29
|
+
// Type instances are singletons within an AssemblyLoadContext, so reference
|
|
30
|
+
// equality and reference hash codes are sufficient and allocation-free.
|
|
31
|
+
|
|
32
|
+
internal readonly record struct MethodKey(Type Type, string Name, int ArgCount, BindingFlags Flags);
|
|
33
|
+
internal readonly record struct PropKey(Type Type, string Name, BindingFlags Flags);
|
|
34
|
+
internal readonly record struct CtorKey(Type Type, int ArgCount);
|
|
35
|
+
|
|
36
|
+
internal readonly struct DispatchEntry(Func<object?, object?[], object?>? invoke, ParameterInfo[] parameters)
|
|
37
|
+
{
|
|
38
|
+
public readonly Func<object?, object?[], object?>? Invoke = invoke;
|
|
39
|
+
public readonly ParameterInfo[] Parameters = parameters;
|
|
40
|
+
public static readonly DispatchEntry Empty = new(null, []);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
internal readonly struct CtorEntry(ConstructorInfo? ctor, ParameterInfo[] parameters)
|
|
44
|
+
{
|
|
45
|
+
public readonly ConstructorInfo? Ctor = ctor;
|
|
46
|
+
public readonly ParameterInfo[] Parameters = parameters;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
internal enum DispatchKind : byte { Void, Primitive, Handle, Collection, Members, TaskHandle }
|
|
50
|
+
|
|
51
|
+
internal readonly struct DispatchResult
|
|
52
|
+
{
|
|
53
|
+
public static readonly DispatchResult Void =
|
|
54
|
+
new(DispatchKind.Void, null, null, 0, null, null, null, null, null);
|
|
55
|
+
|
|
56
|
+
private readonly DispatchKind _kind;
|
|
57
|
+
private readonly object? _value;
|
|
58
|
+
private readonly Type? _type;
|
|
59
|
+
private readonly int _handle;
|
|
60
|
+
private readonly string? _typeName;
|
|
61
|
+
private readonly string[]? _methods;
|
|
62
|
+
private readonly string[]? _properties;
|
|
63
|
+
private readonly string[]? _staticMethods;
|
|
64
|
+
private readonly string[]? _staticProperties;
|
|
65
|
+
private readonly string[]? _readonlyProperties;
|
|
66
|
+
private readonly string[]? _readonlyStaticProperties;
|
|
67
|
+
private readonly string[]? _writeonlyProperties;
|
|
68
|
+
private readonly string[]? _writeonlyStaticProperties;
|
|
69
|
+
|
|
70
|
+
private DispatchResult(DispatchKind kind, object? value, Type? type, int handle,
|
|
71
|
+
string? typeName, string[]? methods, string[]? props,
|
|
72
|
+
string[]? staticMethods, string[]? staticProps,
|
|
73
|
+
string[]? readonlyProps = null, string[]? readonlyStaticProps = null,
|
|
74
|
+
string[]? writeonlyProps = null, string[]? writeonlyStaticProps = null)
|
|
75
|
+
{
|
|
76
|
+
_kind = kind; _value = value; _type = type; _handle = handle;
|
|
77
|
+
_typeName = typeName; _methods = methods; _properties = props;
|
|
78
|
+
_staticMethods = staticMethods; _staticProperties = staticProps;
|
|
79
|
+
_readonlyProperties = readonlyProps; _readonlyStaticProperties = readonlyStaticProps;
|
|
80
|
+
_writeonlyProperties = writeonlyProps; _writeonlyStaticProperties = writeonlyStaticProps;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public static DispatchResult Primitive(object value, Type type)
|
|
84
|
+
=> new(DispatchKind.Primitive, value, type, 0, null, null, null, null, null);
|
|
85
|
+
|
|
86
|
+
public static DispatchResult Handle(int id, string typeName)
|
|
87
|
+
=> new(DispatchKind.Handle, null, null, id, typeName, null, null, null, null);
|
|
88
|
+
|
|
89
|
+
public static DispatchResult TaskHandle(int id, string typeName)
|
|
90
|
+
=> new(DispatchKind.TaskHandle, null, null, id, typeName, null, null, null, null);
|
|
91
|
+
|
|
92
|
+
public static DispatchResult Collection(IEnumerable items)
|
|
93
|
+
=> new(DispatchKind.Collection, items, null, 0, null, null, null, null, null);
|
|
94
|
+
|
|
95
|
+
public static DispatchResult Members(
|
|
96
|
+
string[] methods, string[] props, string[] staticMethods, string[] staticProps,
|
|
97
|
+
string[] readonlyProps, string[] readonlyStaticProps,
|
|
98
|
+
string[] writeonlyProps, string[] writeonlyStaticProps)
|
|
99
|
+
=> new(DispatchKind.Members, null, null, 0, null,
|
|
100
|
+
methods, props, staticMethods, staticProps,
|
|
101
|
+
readonlyProps, readonlyStaticProps, writeonlyProps, writeonlyStaticProps);
|
|
102
|
+
|
|
103
|
+
internal int HandleId() => _handle;
|
|
104
|
+
|
|
105
|
+
public void WriteTo(Utf8JsonWriter w, JsonSerializerOptions opts)
|
|
106
|
+
{
|
|
107
|
+
switch (_kind)
|
|
108
|
+
{
|
|
109
|
+
case DispatchKind.Void:
|
|
110
|
+
w.WriteNullValue();
|
|
111
|
+
break;
|
|
112
|
+
|
|
113
|
+
case DispatchKind.Primitive:
|
|
114
|
+
JsonSerializer.Serialize(w, _value, _type!, opts);
|
|
115
|
+
break;
|
|
116
|
+
|
|
117
|
+
case DispatchKind.Handle:
|
|
118
|
+
w.WriteStartObject();
|
|
119
|
+
w.WriteNumber("__handle"u8, _handle);
|
|
120
|
+
w.WriteString("__type"u8, _typeName);
|
|
121
|
+
// If the bridge has a canonical native pointer for this handle,
|
|
122
|
+
// expose it as a hex string so the runtime can detect and use it.
|
|
123
|
+
if (Bridge.s_nativePtrs.TryGetValue(_handle, out var nativePtr))
|
|
124
|
+
{
|
|
125
|
+
try
|
|
126
|
+
{
|
|
127
|
+
w.WriteString("__native_ptr"u8, nativePtr.ToString("x"));
|
|
128
|
+
}
|
|
129
|
+
catch
|
|
130
|
+
{
|
|
131
|
+
// ignore formatting errors
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
w.WriteEndObject();
|
|
135
|
+
break;
|
|
136
|
+
|
|
137
|
+
case DispatchKind.TaskHandle:
|
|
138
|
+
w.WriteStartObject();
|
|
139
|
+
w.WriteNumber("__handle"u8, _handle);
|
|
140
|
+
w.WriteString("__type"u8, _typeName);
|
|
141
|
+
w.WriteBoolean("__isTask"u8, true);
|
|
142
|
+
w.WriteEndObject();
|
|
143
|
+
break;
|
|
144
|
+
|
|
145
|
+
case DispatchKind.Collection:
|
|
146
|
+
w.WriteStartArray();
|
|
147
|
+
foreach (var item in (IEnumerable)_value!)
|
|
148
|
+
JsonSerializer.Serialize(w, item, item?.GetType() ?? typeof(object), opts);
|
|
149
|
+
w.WriteEndArray();
|
|
150
|
+
break;
|
|
151
|
+
|
|
152
|
+
case DispatchKind.Members:
|
|
153
|
+
w.WriteStartObject();
|
|
154
|
+
WriteStringArray(w, "methods"u8, _methods!);
|
|
155
|
+
WriteStringArray(w, "properties"u8, _properties!);
|
|
156
|
+
WriteStringArray(w, "staticMethods"u8, _staticMethods!);
|
|
157
|
+
WriteStringArray(w, "staticProperties"u8, _staticProperties!);
|
|
158
|
+
WriteStringArray(w, "readonlyProperties"u8, _readonlyProperties!);
|
|
159
|
+
WriteStringArray(w, "readonlyStaticProperties"u8, _readonlyStaticProperties!);
|
|
160
|
+
WriteStringArray(w, "writeonlyProperties"u8, _writeonlyProperties!);
|
|
161
|
+
WriteStringArray(w, "writeonlyStaticProperties"u8,_writeonlyStaticProperties!);
|
|
162
|
+
w.WriteEndObject();
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private static void WriteStringArray(Utf8JsonWriter w, ReadOnlySpan<byte> name, string[] arr)
|
|
168
|
+
{
|
|
169
|
+
w.WriteStartArray(name);
|
|
170
|
+
foreach (var s in arr) w.WriteStringValue(s);
|
|
171
|
+
w.WriteEndArray();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
//
|
|
175
|
+
// Response tags:
|
|
176
|
+
// 0x00 = null 0x01 = false 0x02 = true
|
|
177
|
+
// 0x03 = i32[4] 0x04 = f64[8] 0x05 = string[u32+utf8]
|
|
178
|
+
// 0x06 = handle[i32 + u16+utf8 type]
|
|
179
|
+
// 0x07 = array[u32 count + N tagged items]
|
|
180
|
+
// 0x08 = members{ methods, props, staticMethods, staticProps }
|
|
181
|
+
// 0xFF = error[u32+utf8]
|
|
182
|
+
|
|
183
|
+
public void WriteAsBin(ArrayBufferWriter<byte> outBuf)
|
|
184
|
+
{
|
|
185
|
+
var w = new BinWriter(outBuf);
|
|
186
|
+
switch (_kind)
|
|
187
|
+
{
|
|
188
|
+
case DispatchKind.Void:
|
|
189
|
+
w.WriteByte(0x00);
|
|
190
|
+
break;
|
|
191
|
+
|
|
192
|
+
case DispatchKind.Primitive:
|
|
193
|
+
WritePrimitiveBin(ref w, _value!);
|
|
194
|
+
break;
|
|
195
|
+
|
|
196
|
+
case DispatchKind.Handle:
|
|
197
|
+
w.WriteByte(0x06);
|
|
198
|
+
w.WriteI32(_handle);
|
|
199
|
+
w.WriteString16(_typeName ?? "");
|
|
200
|
+
break;
|
|
201
|
+
|
|
202
|
+
case DispatchKind.TaskHandle:
|
|
203
|
+
w.WriteByte(0x0C);
|
|
204
|
+
w.WriteI32(_handle);
|
|
205
|
+
w.WriteString16(_typeName ?? "");
|
|
206
|
+
break;
|
|
207
|
+
|
|
208
|
+
case DispatchKind.Collection:
|
|
209
|
+
var items = new List<object?>();
|
|
210
|
+
foreach (var item in (IEnumerable)_value!) items.Add(item);
|
|
211
|
+
w.WriteByte(0x07);
|
|
212
|
+
w.WriteU32((uint)items.Count);
|
|
213
|
+
foreach (var item in items) WriteValueBin(ref w, item);
|
|
214
|
+
break;
|
|
215
|
+
|
|
216
|
+
case DispatchKind.Members:
|
|
217
|
+
w.WriteByte(0x08);
|
|
218
|
+
WriteStringArrayBin(ref w, _methods!);
|
|
219
|
+
WriteStringArrayBin(ref w, _properties!);
|
|
220
|
+
WriteStringArrayBin(ref w, _staticMethods!);
|
|
221
|
+
WriteStringArrayBin(ref w, _staticProperties!);
|
|
222
|
+
WriteStringArrayBin(ref w, _readonlyProperties!);
|
|
223
|
+
WriteStringArrayBin(ref w, _readonlyStaticProperties!);
|
|
224
|
+
WriteStringArrayBin(ref w, _writeonlyProperties!);
|
|
225
|
+
WriteStringArrayBin(ref w, _writeonlyStaticProperties!);
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private static void WritePrimitiveBin(ref BinWriter w, object value)
|
|
231
|
+
{
|
|
232
|
+
switch (value)
|
|
233
|
+
{
|
|
234
|
+
case bool b: w.WriteByte(b ? (byte)0x02 : (byte)0x01); break;
|
|
235
|
+
case sbyte v: w.WriteByte(0x03); w.WriteI32(v); break;
|
|
236
|
+
case byte v: w.WriteByte(0x03); w.WriteI32(v); break;
|
|
237
|
+
case short v: w.WriteByte(0x03); w.WriteI32(v); break;
|
|
238
|
+
case ushort v: w.WriteByte(0x03); w.WriteI32(v); break;
|
|
239
|
+
case int v: w.WriteByte(0x03); w.WriteI32(v); break;
|
|
240
|
+
case uint v: w.WriteByte(0x04); w.WriteF64(v); break;
|
|
241
|
+
case long v: w.WriteByte(0x04); w.WriteF64(v); break;
|
|
242
|
+
case ulong v: w.WriteByte(0x04); w.WriteF64(v); break;
|
|
243
|
+
case float v: w.WriteByte(0x04); w.WriteF64(v); break;
|
|
244
|
+
case double v: w.WriteByte(0x04); w.WriteF64(v); break;
|
|
245
|
+
case decimal v: w.WriteByte(0x04); w.WriteF64((double)v); break;
|
|
246
|
+
case string s: w.WriteByte(0x05); w.WriteString32(s); break;
|
|
247
|
+
default: w.WriteByte(0x05); w.WriteString32(value.ToString() ?? ""); break;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
private static void WriteValueBin(ref BinWriter w, object? value)
|
|
252
|
+
{
|
|
253
|
+
if (value is null) { w.WriteByte(0x00); return; }
|
|
254
|
+
var t = value.GetType();
|
|
255
|
+
if (t.IsPrimitive || t == typeof(string) || t == typeof(decimal))
|
|
256
|
+
{
|
|
257
|
+
WritePrimitiveBin(ref w, value);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (value is IEnumerable enumerable)
|
|
261
|
+
{
|
|
262
|
+
var items = new List<object?>();
|
|
263
|
+
foreach (var item in enumerable) items.Add(item);
|
|
264
|
+
w.WriteByte(0x07);
|
|
265
|
+
w.WriteU32((uint)items.Count);
|
|
266
|
+
foreach (var item in items) WriteValueBin(ref w, item);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
var id = Interlocked.Increment(ref Bridge.s_nextHandle);
|
|
270
|
+
Bridge.s_handles[id] = value;
|
|
271
|
+
w.WriteByte(0x06);
|
|
272
|
+
w.WriteI32(id);
|
|
273
|
+
w.WriteString16(t.FullName ?? t.Name);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
private static void WriteStringArrayBin(ref BinWriter w, string[] arr)
|
|
277
|
+
{
|
|
278
|
+
w.WriteU16((ushort)arr.Length);
|
|
279
|
+
foreach (var s in arr) w.WriteString16(s);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
internal static class TaskResultCache
|
|
284
|
+
{
|
|
285
|
+
private static readonly ConcurrentDictionary<Type, Func<Task, object?>> s_cache = new();
|
|
286
|
+
|
|
287
|
+
public static object? GetResult(Task task)
|
|
288
|
+
{
|
|
289
|
+
var taskType = task.GetType();
|
|
290
|
+
if (!taskType.IsGenericType) return null;
|
|
291
|
+
var fn = s_cache.GetOrAdd(taskType, static t =>
|
|
292
|
+
{
|
|
293
|
+
var param = Expression.Parameter(typeof(Task));
|
|
294
|
+
Expression body = Expression.Property(Expression.Convert(param, t), "Result");
|
|
295
|
+
if (body.Type.IsValueType) body = Expression.Convert(body, typeof(object));
|
|
296
|
+
return Expression.Lambda<Func<Task, object?>>(body, param).Compile();
|
|
297
|
+
});
|
|
298
|
+
return fn(task);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
internal static class ValueTaskAsTaskCache
|
|
303
|
+
{
|
|
304
|
+
private static readonly ConcurrentDictionary<Type, Func<object, Task>> s_cache = new();
|
|
305
|
+
|
|
306
|
+
public static Task AsTask(Type valueTaskType, object vt)
|
|
307
|
+
{
|
|
308
|
+
var fn = s_cache.GetOrAdd(valueTaskType, static t =>
|
|
309
|
+
{
|
|
310
|
+
var param = Expression.Parameter(typeof(object));
|
|
311
|
+
var cast = Expression.Convert(param, t);
|
|
312
|
+
var call = Expression.Call(cast, t.GetMethod("AsTask")!);
|
|
313
|
+
return Expression.Lambda<Func<object, Task>>(call, param).Compile();
|
|
314
|
+
});
|
|
315
|
+
return fn(vt);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
@@ -16,5 +16,11 @@
|
|
|
16
16
|
host process is already running on net10. LatestMajor accepts any version >= 9. -->
|
|
17
17
|
<RollForward>LatestMajor</RollForward>
|
|
18
18
|
</PropertyGroup>
|
|
19
|
-
|
|
19
|
+
<Target Name="WriteDotNetToolDone" AfterTargets="Publish">
|
|
20
|
+
<PropertyGroup>
|
|
21
|
+
<DotNetToolDoneFile>$(MSBuildProjectDirectory)\publish\.dotnet_tool_done</DotNetToolDoneFile>
|
|
22
|
+
</PropertyGroup>
|
|
23
|
+
<MakeDir Directories="$(MSBuildProjectDirectory)\publish" Condition="!Exists('$(MSBuildProjectDirectory)\publish')" />
|
|
24
|
+
<WriteLinesToFile File="$(DotNetToolDoneFile)" Lines="done" Overwrite="true" />
|
|
25
|
+
</Target>
|
|
20
26
|
</Project>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@nativescript/windows",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
4
|
-
"description": "NativeScript for using Windows v8",
|
|
5
|
-
"repository": {
|
|
6
|
-
"type": "git",
|
|
7
|
-
"url": "https://github.com/NativeScript/windows.git"
|
|
8
|
-
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"build": "pwsh -File build.ps1",
|
|
11
|
-
"build:x64": "pwsh -File build.ps1 -SkipArm64",
|
|
12
|
-
"build:nodotnet": "pwsh -File build.ps1 -SkipDotnet"
|
|
13
|
-
},
|
|
14
|
-
"keywords": ["nativescript", "windows", "winrt", "uwp"],
|
|
15
|
-
"license": "Apache-2.0",
|
|
16
|
-
"files": [
|
|
17
|
-
"**/*"
|
|
18
|
-
]
|
|
19
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@nativescript/windows",
|
|
3
|
+
"version": "0.1.0-alpha.80",
|
|
4
|
+
"description": "NativeScript for using Windows v8",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/NativeScript/windows.git"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "pwsh -File build.ps1",
|
|
11
|
+
"build:x64": "pwsh -File build.ps1 -SkipArm64",
|
|
12
|
+
"build:nodotnet": "pwsh -File build.ps1 -SkipDotnet"
|
|
13
|
+
},
|
|
14
|
+
"keywords": ["nativescript", "windows", "winrt", "uwp"],
|
|
15
|
+
"license": "Apache-2.0",
|
|
16
|
+
"files": [
|
|
17
|
+
"**/*"
|
|
18
|
+
]
|
|
19
|
+
}
|