20 Commits

Author SHA1 Message Date
Jedd Morgan f406cb8229 wip update for the sample project to use new ui components 2023-06-26 22:13:12 +01:00
Jedd Morgan 62875c0a27 Editor progress bar now works 2023-06-22 17:23:57 +01:00
Jedd Morgan b3c6b59721 Cancellation fixes and editor progress 2023-06-14 17:08:51 +01:00
Jedd Morgan d9f7895b3f Improved Editor Cancellation 2023-06-11 14:39:14 +01:00
Jedd Morgan dc58f6b0b0 wip collections 2023-06-08 23:17:50 +01:00
Jedd Morgan 556a7eaddf Merge remote-tracking branch 'origin/main' into jrm/traversal-refactor 2023-06-07 17:09:27 +01:00
Jedd Morgan 39a79be700 Merge branch 'main' into jrm/traversal-refactor 2023-06-07 17:08:58 +01:00
Jedd Morgan 73ef71f4fd Merge pull request #95 from specklesystems/core/2.14.2
Bumped core to 2.14.2
2023-06-07 15:21:13 +01:00
Jedd Morgan 6a07ecfd5b bumped version number 2023-06-07 15:20:57 +01:00
Jedd Morgan e512df9c82 Bumped core to 2.14.2 2023-06-07 13:54:10 +01:00
Jedd Morgan 59221e89ba Merge pull request #94 from specklesystems/jrm/update-core-2.13.0
Added IsMultiplayer
2023-04-22 01:21:09 +01:00
Jedd Morgan 32533ddb21 Added IsMultiplayer 2023-04-22 01:20:08 +01:00
Jedd Morgan fc537e137f Merge pull request #92 from specklesystems/jrm/update-core-2.13.0
2.13 update
2023-04-22 00:15:01 +01:00
Jedd Morgan 2aaaf6572c Final polish 2023-04-22 00:14:40 +01:00
Jedd Morgan a89e4cdfe7 wip implementation of traversal refactor 2023-04-21 22:34:59 +01:00
Jedd Morgan 9a89255ae8 Fixed build warnings 2023-04-11 21:14:35 +01:00
Jedd Morgan 9f3145eb19 2.13 testing 2023-04-11 17:55:59 +01:00
Jedd Morgan 5dde0dae60 Configure await false fixes deadlocks 2023-04-06 22:50:47 +01:00
Jedd Morgan 0794c53b24 Converter now builds 2023-04-04 20:20:07 +01:00
Jedd Morgan 2973087beb Update objects & core dlls to 2.13 2023-04-04 19:59:48 +01:00
176 changed files with 9632 additions and 1626 deletions
+210
View File
@@ -0,0 +1,210 @@
root = true
# Don't use tabs for indentation.
[*]
indent_style = space
# Microsoft .NET properties
csharp_using_directive_placement = outside_namespace:silent
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
# ReSharper properties
resharper_align_linq_query = false
resharper_align_multiline_calls_chain = true
resharper_align_multiline_extends_list = true
resharper_align_multiline_for_stmt = true
resharper_align_multiline_parameter = true
resharper_align_multiple_declaration = true
resharper_align_multline_type_parameter_constrains = true
resharper_align_multline_type_parameter_list = true
resharper_braces_for_dowhile = not_required
resharper_braces_for_fixed = not_required
resharper_braces_for_lock = not_required
resharper_braces_for_using = not_required
resharper_csharp_align_multiline_calls_chain = false
resharper_csharp_align_multiline_extends_list = false
resharper_csharp_align_multiline_parameter = false
resharper_csharp_int_align_comments = false
resharper_csharp_outdent_commas = true
resharper_csharp_outdent_dots = false
resharper_csharp_wrap_after_declaration_lpar = true
resharper_csharp_wrap_after_invocation_lpar = true
resharper_csharp_wrap_arguments_style = chop_if_long
resharper_csharp_wrap_before_declaration_rpar = true
resharper_csharp_wrap_before_invocation_rpar = false
resharper_csharp_wrap_extends_list_style = chop_if_long
resharper_csharp_wrap_parameters_style = chop_if_long
resharper_force_attribute_style = join
resharper_indent_nested_fixed_stmt = false
resharper_indent_nested_foreach_stmt = true
resharper_indent_nested_for_stmt = true
resharper_indent_nested_lock_stmt = false
resharper_indent_nested_usings_stmt = false
resharper_indent_nested_while_stmt = true
resharper_int_align = false
resharper_int_align_nested_ternary = false
resharper_int_align_switch_expressions = false
resharper_keep_existing_declaration_block_arrangement = true
resharper_keep_existing_declaration_parens_arrangement = false
resharper_keep_existing_embedded_block_arrangement = true
resharper_keep_existing_enum_arrangement = true
resharper_keep_existing_expr_member_arrangement = true
resharper_keep_existing_initializer_arrangement = false
resharper_local_function_body = expression_body
resharper_max_attribute_length_for_same_line = 20
resharper_max_formal_parameters_on_line = 5
resharper_max_initializer_elements_on_line = 0
resharper_max_invocation_arguments_on_line = 5
resharper_outdent_binary_ops = true
resharper_outdent_dots = false
resharper_place_constructor_initializer_on_same_line = false
resharper_place_simple_initializer_on_single_line = true
resharper_prefer_explicit_discard_declaration = false
resharper_wrap_after_declaration_lpar = false
resharper_wrap_before_invocation_rpar = false
resharper_wrap_chained_binary_expressions = chop_if_long
resharper_wrap_chained_binary_patterns = chop_if_long
resharper_wrap_chained_method_calls = chop_if_long
resharper_xmldoc_indent_text = ZeroIndent
# Standard properties
insert_final_newline = true
# (Please don't specify an indent_size here; that has too many unintended consequences.)
# Code files
[*.{cs,csx,vb,vbx}]
indent_size = 4
charset = utf-8
# Xml project files
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
indent_size = 2
space_after_last_pi_attribute = false
# Xml config files
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
indent_size = 2
space_after_last_pi_attribute = false
# JSON files
[*.json]
indent_size = 2
# Dotnet code style settings:
[*.{cs,vb}]
# Sort using and Import directives with System.* appearing first
dotnet_sort_system_directives_first = true
dotnet_separate_import_directive_groups = false
# Avoid "this." and "Me." if not necessary
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
# Use language keywords instead of framework type names for type references
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:silent
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:silent
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
# Modifier preferences
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
dotnet_style_readonly_field = true:suggestion
# Expression-level preferences
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_auto_properties = true:warning
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
# CSharp code style settings:
[*.cs]
# Prefer "var" everywhere
csharp_style_var_elsewhere = false:none
csharp_style_var_for_built_in_types = false:none
csharp_style_var_when_type_is_apparent = false:none
# Prefer method-like constructs to have a block body
csharp_style_expression_bodied_methods = false:suggestion
csharp_style_expression_bodied_constructors = false:suggestion
csharp_style_expression_bodied_operators = true:suggestion
# Prefer property-like constructs to have an expression-body
csharp_style_expression_bodied_properties = true:suggestion
csharp_style_expression_bodied_indexers = true:suggestion
csharp_style_expression_bodied_accessors = true:suggestion
# Suggest more modern language features when available
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Newline settings
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
# Space preferences
csharp_space_after_cast = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_around_binary_operators = before_and_after
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
# Wrapping preferences
csharp_preserve_single_line_statements = true
csharp_preserve_single_line_blocks = true
# Analyzer settings
dotnet_diagnostic.ide0055.severity = none
# Maintainability rules
dotnet_diagnostic.ca1501.severity = warning
dotnet_diagnostic.ca1502.severity = warning
dotnet_diagnostic.ca1505.severity = warning
dotnet_diagnostic.ca1506.severity = warning
dotnet_diagnostic.ca1507.severity = warning
dotnet_diagnostic.ca1508.severity = warning
dotnet_diagnostic.ca1509.severity = warning
# Misc
dotnet_diagnostic.ca1051.severity = none # Do not declare visible instance fields
dotnet_diagnostic.ca1062.severity = none # Public method must check all parameters for null
dotnet_diagnostic.ca1707.severity = none # Remove underscores in names
dotnet_analyzer_diagnostic.category-globalization.severity = none
dotnet_analyzer_diagnostic.category-security.severity = none
dotnet_analyzer_diagnostic.category-interoperability.severity = none
dotnet_analyzer_diagnostic.category-singlefile.severity = none
[*.{appxmanifest,asax,ascx,aspx,axaml,build,c,c++,cc,cginc,compute,cp,cpp,cs,cshtml,cu,cuh,cxx,dtd,fs,fsi,fsscript,fsx,fx,fxh,h,hh,hlsl,hlsli,hlslinc,hpp,hxx,inc,inl,ino,ipp,ixx,master,ml,mli,mpp,mq4,mq5,mqh,nuspec,paml,razor,resw,resx,shader,skin,tpp,usf,ush,vb,xaml,xamlx,xoml,xsd}]
indent_style = space
indent_size = 4
tab_width = 2
+2 -2
View File
@@ -45,14 +45,14 @@ ExportedObj/
*.pidb
*.booproj
*.svd
*.pdb
#*.pdb
*.mdb
*.opendb
*.VC.db
# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
#*.pdb.meta
*.mdb.meta
# Unity3D generated file on crash reports
@@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Threading.Tasks;
using Speckle.ConnectorUnity;
@@ -7,6 +8,7 @@ using Speckle.Core.Credentials;
using Speckle.Core.Transports;
using UnityEngine;
[AddComponentMenu("Speckle/Extras/Manual Receiver")]
[RequireComponent(typeof(RecursiveConverter))]
public class ManualReceive : MonoBehaviour
{
@@ -30,7 +32,8 @@ public class ManualReceive : MonoBehaviour
if(Time.timeSinceLevelLoad > 20) yield return null;
Receive();
}
[ContextMenu(nameof(Receive))]
public void Receive()
{
var account = new Account()
@@ -48,14 +51,17 @@ public class ManualReceive : MonoBehaviour
objectId,
remoteTransport: transport,
localTransport: localTransport,
onErrorAction: (m, e)=> Debug.LogError(m + e),
onErrorAction: (m, e) => Debug.LogError(m + e),
disposeTransports: true
);
if (@base == null) throw new Exception("received data was null!");
Dispatcher.Instance().Enqueue(() =>
{
var parentObject = new GameObject(name);
receiver.RecursivelyConvertToNative(@base, parentObject.transform);
receiver.RecursivelyConvertToNative_Sync(@base, parentObject.transform);
Debug.Log($"Receive {objectId} completed");
});
+79
View File
@@ -0,0 +1,79 @@
using System.Threading;
using System.Threading.Tasks;
using Speckle.ConnectorUnity.Components;
using Speckle.Core.Api;
using Speckle.Core.Models;
using Speckle.Core.Transports;
using UnityEngine;
namespace Extra
{
/// <summary>
/// Script used to generate streams for performance benchmarking in other hostApps.
/// Will send several several commits with a varying number of copies on a GameObject (with children)
/// </summary>
[ExecuteAlways]
[RequireComponent(typeof(SpeckleSender))]
public sealed class PerformanceTestSender : MonoBehaviour
{
[Range(0, 100)]
public int numberOfIterations = 10;
public Vector3 translation = Vector3.forward * 100;
public GameObject objectToSend;
private SpeckleSender sender;
private void Awake()
{
sender = GetComponent<SpeckleSender>();
}
public async Task SendIterations()
{
GameObject go = new GameObject();
for (int i = 0; i < numberOfIterations; i++)
{
Instantiate(objectToSend, translation * i, Quaternion.identity, go.transform);
Base b = sender.Converter.RecursivelyConvertToSpeckle(go, _ => true);
await Send(b, $"{i}");
}
Debug.Log("Done!");
}
private async Task<string> Send(Base data, string branchName)
{
var client = sender.Account.Client;
var stream = sender.Stream.Selected;
ServerTransport transport = new ServerTransport(sender.Account.Selected, stream!.id);
await client.BranchCreate(new BranchCreateInput(){streamId = stream.id, name = branchName});
return await SpeckleSender.SendDataAsync(CancellationToken.None,
remoteTransport: transport,
data: data,
client: client!,
branchName: branchName,
createCommit: true,
onProgressAction: null,
onErrorAction: (m, e) => throw e);
}
}
#if UNITY_EDITOR
[UnityEditor.CustomEditor(typeof(PerformanceTestSender))]
public sealed class PerformanceTestSenderEditor : UnityEditor.Editor
{
public override async void OnInspectorGUI()
{
DrawDefaultInspector();
if (GUILayout.Button("Create and send"))
{
await ((PerformanceTestSender)target).SendIterations();
}
}
}
#endif
}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 2dd598fed5008c44a815ba09e81a2d19
guid: c98b93e32c844fb488992e2e376447a1
MonoImporter:
externalObjects: {}
serializedVersion: 2
+153
View File
@@ -0,0 +1,153 @@
using System;
using System.Collections;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Speckle.ConnectorUnity.Components;
using Speckle.ConnectorUnity.Utils;
using Speckle.Core.Api;
using Speckle.Core.Credentials;
using Speckle.Core.Logging;
using Speckle.Core.Models;
using UnityEngine;
[AddComponentMenu("Speckle/Extras/Receive From Url")]
[RequireComponent(typeof(RecursiveConverter)), ExecuteAlways]
public class ReceiveFromURL : MonoBehaviour
{
[Tooltip("Url of your speckle object/commit/branch/stream")]
public string url;
private RecursiveConverter _converter;
#nullable enable
private CancellationTokenSource? _tokenSource;
void Awake()
{
_converter = GetComponent<RecursiveConverter>();
}
[ContextMenu(nameof(Receive))]
public void Receive()
{
StartCoroutine(Receive_Routine());
}
public IEnumerator Receive_Routine()
{
if (IsBusy()) throw new InvalidOperationException("A receive operation has already started");
_tokenSource = new CancellationTokenSource();
try
{
StreamWrapper sw = new(url);
if (!sw.IsValid)
throw new InvalidOperationException("Speckle url input is not a valid speckle stream/branch/commit");
var accountTask = new Utils.WaitForTask<Account>(async () => await GetAccount(sw));
yield return accountTask;
_tokenSource.Token.ThrowIfCancellationRequested();
using Client c = new(accountTask.Result);
var objectIdTask = new Utils.WaitForTask<(string, Commit?)>(async () => await GetObjectID(sw, c));
yield return objectIdTask;
(string objectId, Commit? commit) = objectIdTask.Result;
Debug.Log($"Receiving from {sw.ServerUrl}...");
var receiveTask = new Utils.WaitForTask<Base>(async () => await SpeckleReceiver.ReceiveAsync(
c,
sw.StreamId,
objectId,
commit,
cancellationToken: _tokenSource.Token));
yield return receiveTask;
Debug.Log("Converting to native...");
_converter.RecursivelyConvertToNative_Sync(receiveTask.Result, transform);
}
finally
{
_tokenSource.Dispose();
_tokenSource = null;
}
}
private async Task<(string objectId, Commit? commit)> GetObjectID(StreamWrapper sw, Client client)
{
string objectId;
Commit? commit = null;
//OBJECT URL
if (!string.IsNullOrEmpty(sw.ObjectId))
{
objectId = sw.ObjectId;
}
//COMMIT URL
else if (!string.IsNullOrEmpty(sw.CommitId))
{
commit = await client.CommitGet(sw.StreamId, sw.CommitId).ConfigureAwait(false);
objectId = commit.referencedObject;
}
//BRANCH URL OR STREAM URL
else
{
var branchName = string.IsNullOrEmpty(sw.BranchName) ? "main" : sw.BranchName;
var branch = await client.BranchGet(sw.StreamId, branchName, 1).ConfigureAwait(false);
if (!branch.commits.items.Any())
throw new SpeckleException("The selected branch has no commits.");
commit = branch.commits.items[0];
objectId = branch.commits.items[0].referencedObject;
}
return (objectId, commit);
}
[ContextMenu(nameof(Cancel))]
public void Cancel()
{
if (IsNotBusy()) throw new InvalidOperationException("There are no pending receive operations to cancel");
_tokenSource!.Cancel();
}
[ContextMenu(nameof(Cancel), true)]
public bool IsBusy()
{
return _tokenSource is not null;
}
[ContextMenu(nameof(Receive), true)]
internal bool IsNotBusy() => !IsBusy();
private void OnDisable()
{
_tokenSource?.Cancel();
}
private async Task<Account> GetAccount(StreamWrapper sw)
{
Account account;
try
{
account = await sw.GetAccount().ConfigureAwait(false);
}
catch (SpeckleException e)
{
if (string.IsNullOrEmpty(sw.StreamId))
throw e;
//Fallback to a non authed account
account = new Account
{
token = "",
serverInfo = new ServerInfo { url = sw.ServerUrl },
userInfo = new UserInfo()
};
}
return account;
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 942bf0cb27c5c5045bc4cbb7fc0fad71
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+1
View File
@@ -9,6 +9,7 @@ using UnityEngine;
using UnityEngine.Events;
[RequireComponent(typeof(Sender)), ExecuteAlways]
[Obsolete]
public class SendChildrenToSpeckle : MonoBehaviour
{
public LayerMask layerMask;
+1 -1
View File
@@ -1,4 +1,4 @@
{
"name": "Speckle.Extra",
"references":[ "GUID:eed1b8b83e2c0074d9e5de2348e3ff72", "GUID:e6adfdc4e436206479f48eafc82f32b5" ]
"references":[ "GUID:eed1b8b83e2c0074d9e5de2348e3ff72", "GUID:e6adfdc4e436206479f48eafc82f32b5", "GUID:d274441ecc3eb3f43b093eec1503d681", "GUID:50d889142fdf9de4b8501c6eaa4b3225" ]
}
+3 -2
View File
@@ -10,7 +10,8 @@ using UnityEngine.UI;
using Text = UnityEngine.UI.Text;
namespace Speckle.ConnectorUnity
{
{
[Obsolete]
public class InteractionLogic : MonoBehaviour
{
private Receiver receiver;
@@ -216,4 +217,4 @@ namespace Speckle.ConnectorUnity
});
}
}
}
}
+3 -1
View File
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using Speckle.Core.Credentials;
@@ -8,6 +9,7 @@ using Stream = Speckle.Core.Api.Stream;
namespace Speckle.ConnectorUnity
{
[Obsolete]
public class SpeckleExamples : MonoBehaviour
{
public Text SelectStreamText;
@@ -129,4 +131,4 @@ namespace Speckle.ConnectorUnity
}
}
}
}
}
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
{
"name": "Editor",
"rootNamespace": "",
"name": "EditorTests",
"rootNamespace": "Speckle.ConnectorUnity.Tests",
"references": [
"UnityEngine.TestRunner",
"UnityEditor.TestRunner",
-96
View File
@@ -1,96 +0,0 @@
using System;
using System.Collections;
using System.Diagnostics;
using System.Threading.Tasks;
using NUnit.Framework;
using Objects.Utils;
using Speckle.Core.Api;
using Speckle.Core.Models;
using Speckle.Core.Models.Extensions;
using UnityEngine;
using UnityEngine.TestTools;
public class PerformanceTest
{
private static readonly string[] dataSource = new[]
{
"https://latest.speckle.dev/streams/24c3741255/commits/0925840e09"
};
//This method is much faster
[Test, TestCaseSource(nameof(dataSource))]
public void Receive_GetAwaiterResult(string stream)
{
var stopwatch = Stopwatch.StartNew();
Helpers.Receive(stream).GetAwaiter().GetResult();
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
Assert.That(stopwatch.ElapsedMilliseconds, Is.Zero);
}
//This method takes around 46 seconds to complete
[Test, TestCaseSource(nameof(dataSource))]
public void Receive_TaskRunAsync(string stream)
{
var stopwatch = Stopwatch.StartNew();
Task.Run(async () =>
{
await Helpers.Receive(stream);
}).GetAwaiter().GetResult();
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
Assert.That(stopwatch.ElapsedMilliseconds, Is.Zero);
}
// [UnityTest, TestCaseSource(nameof(dataSource))]
// public IEnumerable Receive_Coroutine(string stream)
// {
// var stopwatch = Stopwatch.StartNew();
//
// Task t = Helpers.Receive(stream);
// t.Start();
//
// yield return new WaitUntil(() => !t.IsCompleted || stopwatch.ElapsedMilliseconds >= 100000);
//
// stopwatch.Stop();
// Console.WriteLine(stopwatch.ElapsedMilliseconds);
// Assert.That(stopwatch.ElapsedMilliseconds, Is.Zero);
// Assert.True(t.IsCompletedSuccessfully);
// }
//This method takes around 46 seconds to complete
[Test]
public void TestTriangulate()
{
Base b = Task.Run(async () =>
{
return await Helpers.Receive("https://speckle.xyz/streams/4a8fd0c6b6/commits/067bf723b1");
}).GetAwaiter().GetResult();
foreach (Base child in b.Traverse(b => b is Objects.Geometry.Mesh))
{
if(child is not Objects.Geometry.Mesh m) continue;
var stopwatch = Stopwatch.StartNew();
m.TriangulateMesh();
Console.WriteLine($"took {stopwatch.ElapsedMilliseconds:ms} to triangulate {child.id}");
}
}
}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5a4f4baa829261d438b740c7d3028756
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+18
View File
@@ -0,0 +1,18 @@
using NUnit.Framework;
using UnityEngine;
namespace Speckle.ConnectorUnity.Tests
{
public abstract class ComponentTest<T> where T : Component
{
protected T sut;
[SetUp]
public void Setup()
{
GameObject go = new();
sut = go.AddComponent<T>();
Assert.That(sut, Is.Not.Null);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4e2fe277dd9c47ad998138dcdbb024ae
timeCreated: 1686757093
@@ -0,0 +1,50 @@
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using NUnit.Framework;
using NUnit.Framework.Constraints;
using Speckle.ConnectorUnity.Components;
using Speckle.ConnectorUnity.Wrappers;
using Speckle.Core.Api;
using Speckle.Core.Models;
using UnityEngine;
using UnityEngine.TestTools;
namespace Speckle.ConnectorUnity.Tests
{
[TestFixture, TestOf(typeof(RecursiveConverter))]
public class ConvertToNativeTests : ComponentTest<RecursiveConverter>
{
private static IEnumerable<string> TestCases()
{
yield return @"https://latest.speckle.dev/streams/c1faab5c62/commits/704984e22d";
}
private static Base Receive(string stream)
{
return Task.Run(async () => await Helpers.Receive(stream)).Result;
}
[Test, TestCaseSource(nameof(TestCases))]
public void ToNative_Passes(string stream)
{
Base testCase = Receive(stream);
var results = sut.RecursivelyConvertToNative_Sync(testCase, null);
Assert.That(results, Has.Count.GreaterThan(0));
Assert.That(results, HasSomeComponent<Transform>());
Assert.That(results, HasSomeComponent<MeshRenderer>());
Assert.That(results, HasSomeComponent<SpeckleProperties>());
}
private static Constraint HasSomeComponent<T>() where T : Component
{
return Has.Some.Matches<ConversionResult>(
x =>
{
return x.WasSuccessful(out var success, out _)
&& success.GetComponent<T>();
});
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3d9b0fc7baaf51a4a8e2bcefad8bd7b3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,28 @@
{
"name": "PlayModeTests",
"rootNamespace": "Speckle.ConnectorUnity.Tests",
"references": [
"UnityEngine.TestRunner",
"UnityEditor.TestRunner",
"Speckle.ConnectorUnity.Components",
"Utils",
"Speckle.ConnectorUnity.Wrappers"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": true,
"precompiledReferences": [
"nunit.framework.dll",
"SpeckleCore2.dll",
"Objects.dll"
],
"autoReferenced": false,
"defineConstraints": [
"UNITY_INCLUDE_TESTS"
],
"versionDefines": [],
"noEngineReferences": false
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 79301723eb79d2745ab1e1a9360f6f2d
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,73 @@
#nullable enable
using System;
using System.Collections;
using NUnit.Framework;
using Speckle.ConnectorUnity.Components;
using Speckle.Core.Models;
using UnityEngine;
using UnityEngine.TestTools;
namespace Speckle.ConnectorUnity.Tests
{
[TestFixture, TestOf(typeof(SpeckleReceiver))]
public sealed class SpeckleReceiverTests : ComponentTest<SpeckleReceiver>
{
[UnityTest]
public IEnumerator ReceiveAsync_Succeeds()
{
yield return null;
var task = new Utils.Utils.WaitForTask<Base>(async () => await sut.ReceiveAsync(default));
yield return task;
Base myBase = task.Result;
Assert.That(myBase, Is.Not.Null);
}
[UnityTest]
public IEnumerator ReceiveAndConvert_Async_Succeeds()
{
Transform expectedParent = new GameObject("parent").transform;
yield return null;
bool wasSuccessful = false;
Transform? actualParent = null;
sut.OnComplete.AddListener(t =>
{
wasSuccessful = true;
actualParent = t;
});
sut.OnErrorAction.AddListener((_, ex) => throw new Exception("Failed", ex));
sut.ReceiveAndConvert_Async(expectedParent);
yield return new WaitUntil(() => wasSuccessful);
Assert.That(actualParent, Is.EqualTo(expectedParent));
}
[UnityTest]
public IEnumerator ReceiveAndConvert_Routine_Succeeds()
{
Transform expectedParent = new GameObject("parent").transform;
yield return null;
bool wasSuccessful = false;
Transform? actualParent = null;
sut.OnComplete.AddListener(t =>
{
wasSuccessful = true;
actualParent = t;
});
sut.OnErrorAction.AddListener((_, ex) => throw new Exception("Failed", ex));
yield return sut.ReceiveAndConvert_Routine(expectedParent);
yield return new WaitUntil(() => wasSuccessful);
Assert.That(actualParent, Is.EqualTo(expectedParent));
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1756c50dd28a4e341a70866daa68a8d5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+3 -3
View File
@@ -1,9 +1,9 @@
{
"dependencies": {
"com.unity.2d.sprite": "1.0.0",
"com.unity.collab-proxy": "1.17.6",
"com.unity.ide.rider": "3.0.16",
"com.unity.ide.visualstudio": "2.0.16",
"com.unity.collab-proxy": "2.0.1",
"com.unity.ide.rider": "3.0.18",
"com.unity.ide.visualstudio": "2.0.17",
"com.unity.ide.vscode": "1.2.5",
"com.unity.test-framework": "1.1.31",
"com.unity.textmeshpro": "3.0.6",
+4 -24
View File
@@ -7,12 +7,10 @@
"dependencies": {}
},
"com.unity.collab-proxy": {
"version": "1.17.6",
"version": "2.0.1",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.services.core": "1.0.1"
},
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.ext.nunit": {
@@ -23,7 +21,7 @@
"url": "https://packages.unity.com"
},
"com.unity.ide.rider": {
"version": "3.0.16",
"version": "3.0.18",
"depth": 0,
"source": "registry",
"dependencies": {
@@ -32,7 +30,7 @@
"url": "https://packages.unity.com"
},
"com.unity.ide.visualstudio": {
"version": "2.0.16",
"version": "2.0.17",
"depth": 0,
"source": "registry",
"dependencies": {
@@ -47,24 +45,6 @@
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.nuget.newtonsoft-json": {
"version": "3.0.2",
"depth": 2,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.services.core": {
"version": "1.6.0",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.nuget.newtonsoft-json": "3.0.2",
"com.unity.modules.androidjni": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.sysroot": {
"version": "2.0.3",
"depth": 1,
@@ -1,9 +1,8 @@
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
using Speckle.Core.Api;
using Speckle.Core.Models;
using Speckle.Core.Models.GraphTraversal;
using UnityEditor;
using UnityEngine;
@@ -18,6 +17,77 @@ namespace Speckle.ConnectorUnity.Components.Editor
private bool foldOutStatus = true;
private Texture2D? previewImage;
public override async void OnInspectorGUI()
{
var speckleReceiver = (SpeckleReceiver)target;
DrawDefaultInspector();
//Preview image
{
foldOutStatus = EditorGUILayout.Foldout(foldOutStatus, "Preview Image");
if (foldOutStatus)
{
Rect rect = GUILayoutUtility.GetAspectRect(7f / 4f);
if (previewImage != null) GUI.DrawTexture(rect, previewImage);
}
}
//TODO: Draw events in a collapsed region
//Receive settings
{
bool prev = GUI.enabled;
GUI.enabled = !speckleReceiver.IsReceiving;
//Receive button
bool userRequestedReceive = GUILayout.Button("Receive!");
bool selection = EditorGUILayout.ToggleLeft("Generate Assets", generateAssets);
if (generateAssets != selection)
{
generateAssets = selection;
UpdateGenerateAssets();
}
GUI.enabled = prev;
if (speckleReceiver.IsReceiving)
{
var value = Progress.globalProgress; //NOTE: this may include non-speckle items...
var percent = Math.Max(0, Mathf.Ceil(value * 100));
Debug.Log(value);
var rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight);
EditorGUI.ProgressBar(rect, value, $"{percent}%");
}
else if (userRequestedReceive)
{
var id = Progress.Start(
"Receiving Speckle data",
"Fetching commit data", Progress.Options.Sticky);
Progress.ShowDetails();
try
{
await ReceiveSelection(id).ConfigureAwait(true);
Progress.Finish(id);
}
catch (OperationCanceledException ex)
{
Progress.Finish(id, Progress.Status.Canceled);
Debug.Log($"Receive operation cancelled\n{ex}", this);
}
catch (Exception ex)
{
Progress.Finish(id, Progress.Status.Failed);
Debug.LogError($"Receive operation failed {ex}", this);
}
finally
{
EditorUtility.ClearProgressBar();
}
}
}
}
public void OnEnable()
{
Init();
@@ -28,6 +98,7 @@ namespace Speckle.ConnectorUnity.Components.Editor
Init();
}
private void Init()
{
var speckleReceiver = (SpeckleReceiver) target;
@@ -42,40 +113,92 @@ namespace Speckle.ConnectorUnity.Components.Editor
((SpeckleReceiver)target).GetPreviewImage(t => previewImage = t);
}
public override async void OnInspectorGUI()
private async Task ReceiveSelection(int progressId)
{
var speckleReceiver = (SpeckleReceiver) target;
var speckleReceiver = (SpeckleReceiver)target;
DrawDefaultInspector();
//Preview image
foldOutStatus = EditorGUILayout.Foldout(foldOutStatus, "Preview Image");
if (foldOutStatus)
bool shouldCancel = false;
Progress.RegisterCancelCallback(progressId, () =>
{
Rect rect = GUILayoutUtility.GetAspectRect(7f/4f);
if(previewImage != null) GUI.DrawTexture(rect, previewImage);
speckleReceiver.Cancel();
shouldCancel = true;
return true;
});
Base commitObject;
try
{
var token = speckleReceiver.BeginOperation();
commitObject = await Task.Run(async () => await ReceiveCommit(progressId).ConfigureAwait(false),
token
)
.ConfigureAwait(true);
}
finally
{
speckleReceiver.FinishOperation();
}
//Receive button
bool receive = GUILayout.Button("Receive!");
int childrenConverted = 0;
int childrenFailed = 0;
bool selection = EditorGUILayout.ToggleLeft("Generate Assets", generateAssets);
if (generateAssets != selection)
int totalChildren = (int) Math.Min(commitObject.totalChildrenCount, int.MaxValue);
float totalChildrenFloat = commitObject.totalChildrenCount;
var convertProgress = Progress.Start("Converting To Native", "Preparing...", Progress.Options.Indefinite | Progress.Options.Sticky, progressId);
bool BeforeConvert(TraversalContext context)
{
generateAssets = selection;
UpdateGenerateAssets();
}
//TODO: Draw events in a collapsed region
Base b = context.current;
if (receive)
{
await ReceiveAndConvert(speckleReceiver);
//NOTE: progress wont reach 100% because not all objects are convertable
float progress = (childrenConverted + childrenFailed) / totalChildrenFloat;
if (shouldCancel) return false;
shouldCancel = EditorUtility.DisplayCancelableProgressBar(
"Converting To Native...",
$"{b.speckle_type} - {b.id}",
progress);
return !shouldCancel;
}
foreach (var conversionResult in speckleReceiver.Converter.RecursivelyConvertToNative_Enumerable(
commitObject,
speckleReceiver.transform,
BeforeConvert))
{
Base speckleObject = conversionResult.SpeckleObject;
if (conversionResult.WasSuccessful(out _, out var ex))
{
childrenConverted++;
}
else
{
childrenFailed++;
Debug.LogWarning(
$"Failed to convert Speckle object of type {speckleObject.speckle_type}\n{ex}",
this);
}
Progress.Report(progressId, childrenConverted + childrenFailed, totalChildren, "Receiving objects");
if (shouldCancel) break;
}
var resultString = $"{childrenConverted} {nameof(GameObject)}s created";
if (childrenFailed != 0) resultString += $", {childrenFailed} objects failed to convert!";
Debug.Log(shouldCancel
? $"Stopped converting to native: The operation has been cancelled - {resultString}\n "
: $"Finished converting to native.\n{resultString}",
speckleReceiver);
Progress.Finish(convertProgress);
if (shouldCancel) throw new OperationCanceledException("Conversion operation canceled through editor dialogue");
}
private void UpdateGenerateAssets()
@@ -84,114 +207,75 @@ namespace Speckle.ConnectorUnity.Components.Editor
speckleReceiver.Converter.AssetCache.nativeCaches = NativeCacheFactory.GetDefaultNativeCacheSetup(generateAssets);
}
public async Task<GameObject?> ReceiveAndConvert(SpeckleReceiver speckleReceiver)
private async Task<Base> ReceiveCommit(int progressId)
{
speckleReceiver.CancellationTokenSource?.Cancel();
if (!speckleReceiver.GetSelection(out Client? client, out _, out Commit? commit, out string? error))
{
Debug.LogWarning($"Not ready to receive: {error}", speckleReceiver);
return null;
}
Base? commitObject = await ReceiveCommit(speckleReceiver, client.ServerUrl);
var speckleReceiver = (SpeckleReceiver)target;
if (commitObject == null) return null;
string serverLogName = speckleReceiver.Account.Client?.ServerUrl ?? "Speckle";
var gameObject = Convert(speckleReceiver, commitObject, commit.id);
Debug.Log($"Successfully received and converted commit: {commit.id}", target);
return gameObject;
}
private GameObject Convert(SpeckleReceiver receiver, Base commitObject, string name)
{
//Convert Speckle Objects
int childrenConverted = 0;
float totalChildren = commitObject.totalChildrenCount;
void BeforeConvertCallback(Base b)
{
//TODO: this is an incorrect way of measuring progress, as totalChildren != total convertable children
float progress = childrenConverted++ / totalChildren;
EditorUtility.DisplayProgressBar("Converting To Native...",
$"{b.speckle_type} - {b.id}",
progress);
}
var go = receiver.ConvertToNativeWithCategories(commitObject,
name, BeforeConvertCallback);
go.transform.SetParent(receiver.transform);
return go;
}
private async Task<Base?> ReceiveCommit(SpeckleReceiver speckleReceiver, string serverLogName)
{
string message = $"Receiving data from {serverLogName}...";
EditorUtility.DisplayProgressBar(message, "", 0);
int transport = Progress.Start($"Downloading data from {serverLogName}", "Waiting...", Progress.Options.Sticky, progressId);
int deserialize = Progress.Start("Deserializing data", "Waiting...", Progress.Options.Sticky, progressId);
Progress.SetPriority(transport, Progress.Priority.High);
var totalObjectCount = 1;
void OnTotalChildrenKnown(int count)
{
totalObjectCount = count;
};
Progress.Report(progressId, 0, totalObjectCount, "Receiving objects");
}
void OnProgress(ConcurrentDictionary<string, int> dict)
{
var currentProgress = dict.Values.Average();
var progress = (float) currentProgress / totalObjectCount;
EditorApplication.delayCall += () =>
bool r = dict.TryGetValue("RemoteTransport", out int rtProgress);
bool l = dict.TryGetValue("SQLite", out int ltProgress);
if (r || l)
{
bool shouldCancel = EditorUtility.DisplayCancelableProgressBar(message,
$"{currentProgress}/{totalObjectCount}",
progress);
if (shouldCancel)
{
CancelReceive();
}
};
};
void OnError(string message, Exception e)
{
if (e is not OperationCanceledException)
{
Debug.LogError($"Receive failed: {message}\n{e}", speckleReceiver);
var fetched = (rtProgress + ltProgress);
Progress.Report(transport, fetched, totalObjectCount, $"{fetched}/{totalObjectCount}");
}
CancelReceive();
};
Base? commitObject = null;
if (dict.TryGetValue("DS", out int tsProgress))
{
tsProgress--; //The root object isn't included, so we add an extra 1
Progress.Report(deserialize,tsProgress, totalObjectCount, $"{tsProgress}/{totalObjectCount}");
Progress.Report(progressId,tsProgress, totalObjectCount);
}
}
Base commitObject;
try
{
speckleReceiver.OnTotalChildrenCountKnown.AddListener(OnTotalChildrenKnown);
speckleReceiver.OnReceiveProgressAction.AddListener(OnProgress);
speckleReceiver.OnErrorAction.AddListener(OnError);
commitObject = await speckleReceiver.ReceiveAsync();
if (commitObject == null)
{
Debug.LogWarning($"Receive warning: Receive operation returned null", speckleReceiver);
}
commitObject = await speckleReceiver.ReceiveAsync(speckleReceiver.CancellationToken)
.ConfigureAwait(false);
Progress.Finish(transport);
Progress.Finish(deserialize);
}
catch(OperationCanceledException)
{
Progress.Finish(transport, Progress.Status.Canceled);
Progress.Finish(deserialize, Progress.Status.Canceled);
throw;
}
catch(Exception)
{
Progress.Finish(transport, Progress.Status.Failed);
Progress.Finish(deserialize, Progress.Status.Failed);
throw;
}
finally
{
speckleReceiver.OnTotalChildrenCountKnown.RemoveListener(OnTotalChildrenKnown);
speckleReceiver.OnReceiveProgressAction.RemoveListener(OnProgress);
speckleReceiver.OnErrorAction.RemoveListener(OnError);
EditorApplication.delayCall += EditorUtility.ClearProgressBar;
}
return commitObject;
}
private void CancelReceive()
{
((SpeckleReceiver)target).CancellationTokenSource?.Cancel();
EditorApplication.delayCall += EditorUtility.ClearProgressBar;
}
[MenuItem("GameObject/Speckle/Speckle Connector", false, 10)]
static void CreateCustomGameObject(MenuCommand menuCommand) {
static void CreateCustomGameObject(MenuCommand menuCommand)
{
// Create a custom game object
GameObject go = new GameObject("Speckle Connector");
// Ensure it gets reparented if this was a context click (otherwise does nothing)
@@ -209,5 +293,6 @@ namespace Speckle.ConnectorUnity.Components.Editor
EditorGUIUtility.SetIconForObject(go, icon);
#endif
}
}
}
@@ -106,12 +106,6 @@ namespace Speckle.ConnectorUnity.Components.Editor
SceneManager.GetActiveScene().GetRootGameObjects(),
go => go.activeInHierarchy);
}
private void CancelSend()
{
((SpeckleReceiver)target).CancellationTokenSource?.Cancel();
EditorApplication.delayCall += EditorUtility.ClearProgressBar;
}
}
}
@@ -26,7 +26,7 @@ namespace Speckle.ConnectorUnity.Components.Editor
private static bool generateAssets;
public int StreamsLimit { get; set; } = 30;
public int BranchesLimit { get; set; } = 30;
public int BranchesLimit { get; set; } = 75;
public int CommitsLimit { get; set; } = 25;
private int SelectedAccountIndex
@@ -163,9 +163,10 @@ namespace Speckle.ConnectorUnity.Components.Editor
try
{
Commit selectedCommit = Branches[SelectedBranchIndex].commits.items[SelectedCommitIndex];
// Receive Speckle Objects
var @base = await Operations.Receive(
Branches[SelectedBranchIndex].commits.items[SelectedCommitIndex].referencedObject,
selectedCommit.referencedObject,
remoteTransport: transport,
onProgressAction: dict =>
{
@@ -179,8 +180,15 @@ namespace Speckle.ConnectorUnity.Components.Editor
);
EditorUtility.ClearProgressBar();
Analytics.TrackEvent(SelectedAccount, Analytics.Events.Receive);
Analytics.TrackEvent(SelectedAccount, Analytics.Events.Receive, new Dictionary<string, object>()
{
{"mode", nameof(StreamManagerEditor)},
{"sourceHostApp", HostApplications.GetHostAppFromString(selectedCommit.sourceApplication).Slug},
{"sourceHostAppVersion", selectedCommit.sourceApplication ?? ""},
{"hostPlatform", Application.platform.ToString()},
{"isMultiplayer", selectedCommit.authorId != SelectedAccount.userInfo.id},
});
//Convert Speckle Objects
int childrenConverted = 0;
@@ -364,4 +372,4 @@ namespace Speckle.ConnectorUnity.Components.Editor
}
}
}
}
}
@@ -46,8 +46,8 @@ namespace Speckle.ConnectorUnity.Wrappers.Selection.Editor
("Description", s => s.description),
("Is Public", s => s.isPublic.ToString()),
("Role", s => s.role),
("Created at", s => s.createdAt),
("Updated at", s => s.updatedAt),
("Created at", s => s.createdAt.ToString()),
("Updated at", s => s.updatedAt.ToString()),
};
}
}
@@ -84,7 +84,7 @@ namespace Speckle.ConnectorUnity.Wrappers.Selection.Editor
{
("Commit Id", s => s.id),
("Author Name", s => s.authorName),
("Created At", s => s.createdAt),
("Created At", s => s.createdAt.ToString()),
("Source Application", s => s.sourceApplication),
("Reference Object Id", s => s.referencedObject),
};
@@ -34,12 +34,16 @@ namespace Speckle.ConnectorUnity.Wrappers.Editor
.Where(x => x.FullName != null)
.Select(x => x.FullName!.Replace('.', '/'));
var manualTypes = new [] { typeof(Base), typeof(Collection)};
var manualStrings = new []{ nameof(Base), nameof(Collection)};
//Manually Add `Base`
SpeckleTypeOptions = options.Concat(manualTypes).ToArray();
SpeckleTypeOptionStrings = strings.Concat(manualStrings).ToArray();
SpeckleTypeOptionStrings = strings.Append(nameof(Base)).ToArray();
SpeckleTypeOptions = options.Append(typeof(Base)).ToArray();
Debug.Assert(SpeckleTypeOptions.Length == SpeckleTypeOptionStrings.Length);
}
private static GUILayoutOption[] propLayoutOptions = { GUILayout.ExpandWidth(true) };
public override void OnInspectorGUI()
@@ -5,10 +5,13 @@ using Speckle.Core.Logging;
using Speckle.Core.Transports;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Sentry;
using Speckle.ConnectorUnity.Components;
using Speckle.ConnectorUnity.Utils;
using Speckle.Core.Kits;
using UnityEngine;
@@ -18,7 +21,8 @@ namespace Speckle.ConnectorUnity
/// A Speckle Receiver, it's a wrapper around a basic Speckle Client
/// that handles conversions and subscriptions for you
/// </summary>
[RequireComponent( typeof( RecursiveConverter ) )]
[RequireComponent(typeof(RecursiveConverter))]
[Obsolete]
public class Receiver : MonoBehaviour
{
public string StreamId;
@@ -93,7 +97,7 @@ namespace Speckle.ConnectorUnity
if (!mainBranch.commits.items.Any())
throw new Exception("This branch has no commits");
var commit = mainBranch.commits.items[0];
GetAndConvertObject(commit.referencedObject, commit.id);
GetAndConvertObject(commit.referencedObject, commit.id, commit.sourceApplication, commit.authorId);
}
catch (Exception e)
{
@@ -116,12 +120,12 @@ namespace Speckle.ConnectorUnity
if (e.branchName == BranchName)
{
Debug.Log("New commit created");
GetAndConvertObject(e.objectId, e.id);
GetAndConvertObject(e.objectId, e.id, e.sourceApplication, e.authorId);
}
}
private async void GetAndConvertObject(string objectId, string commitId)
private async void GetAndConvertObject(string objectId, string commitId, string sourceApplication, string authorId)
{
try
{
@@ -136,7 +140,14 @@ namespace Speckle.ConnectorUnity
disposeTransports: true
);
Analytics.TrackEvent(Client.Account, Analytics.Events.Receive);
Analytics.TrackEvent(Client.Account, Analytics.Events.Receive, new Dictionary<string, object>()
{
{"mode", nameof(Receiver)},
{"sourceHostApp", HostApplications.GetHostAppFromString(sourceApplication).Slug},
{"sourceHostAppVersion", sourceApplication ?? ""},
{"hostPlatform", Application.platform.ToString()},
{"isMultiplayer", authorId != null && authorId != Client.Account.userInfo.id},
});
Dispatcher.Instance().Enqueue(() =>
{
@@ -186,4 +197,4 @@ namespace Speckle.ConnectorUnity
#endregion
}
}
}
@@ -21,6 +21,7 @@ namespace Speckle.ConnectorUnity
/// that handles conversions for you
/// </summary>
[RequireComponent(typeof(RecursiveConverter)), ExecuteAlways]
[Obsolete]
public class Sender : MonoBehaviour
{
@@ -146,4 +147,4 @@ namespace Speckle.ConnectorUnity
#endregion
}
}
}
@@ -2,17 +2,225 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Speckle.ConnectorUnity.Utils;
using Speckle.Core.Logging;
using Speckle.Core.Models;
using Speckle.Core.Models.GraphTraversal;
using UnityEngine;
namespace Speckle.ConnectorUnity.Components
{
/// <summary>
/// Struct that encapsulates the result of a <see cref="RecursiveConverter"/> ToNative conversion of a single Speckle Object (<see cref="Base"/>)
/// </summary>
public readonly struct ConversionResult
{
/// <summary>
/// The context that was converted ToNative
/// </summary>
public readonly TraversalContext traversalContext;
/// <summary>
/// The result of conversion a successful conversion
/// </summary>
public readonly GameObject? converted;
/// <summary>
/// The result of conversion a failed conversion
/// </summary>
public readonly Exception? exception;
/// <summary>
/// Constructor used for Successful conversions
/// </summary>
/// <param name="traversalContext">The current traversal context</param>
/// <param name="converted">The resultant ToNative conversion of <see cref="TraversalContext.current"/> context object</param>
/// <exception cref="ArgumentNullException"/>
public ConversionResult(TraversalContext traversalContext, [NotNull] GameObject? converted)
: this(traversalContext, converted, null)
{
if (converted is null) throw new ArgumentNullException(nameof(converted));
}
/// <summary>
/// Constructor used for Failed conversions
/// </summary>
/// <param name="traversalContext">The current conversion</param>
/// <param name="exception">The operation halting exception that occured</param>
/// <param name="converted">Optional converted GameObject</param>
/// <exception cref="ArgumentNullException"/>
public ConversionResult(TraversalContext traversalContext, [NotNull] Exception? exception,
GameObject? converted = null)
: this(traversalContext, converted, exception)
{
if (exception is null) throw new ArgumentNullException(nameof(exception));
}
private ConversionResult(TraversalContext traversalContext, GameObject? converted, Exception? exception)
{
this.traversalContext = traversalContext;
this.converted = converted;
this.exception = exception;
}
/// <summary>
///
/// </summary>
/// <param name="converted">The converted <see cref="GameObject"/></param>
/// <param name="exception">The <see cref="exception"/> that occured during conversion</param>
/// <returns>True if the conversion was successful</returns>
public bool WasSuccessful(
[NotNullWhen(true)] out GameObject? converted,
[NotNullWhen(false)] out Exception? exception)
{
converted = this.converted;
exception = this.exception;
return WasSuccessful();
}
public bool WasSuccessful() => this.exception == null;
public Base SpeckleObject => traversalContext.current;
}
public partial class RecursiveConverter
{
/// <inheritdoc cref="RecursivelyConvertToNative_Enumerable"/>
/// <remarks>Calling this function will perform the conversion process synchronously</remarks>
/// <returns>The conversion result</returns>
public List<ConversionResult> RecursivelyConvertToNative_Sync(
Base rootObject,
Transform? parent,
Predicate<TraversalContext>? predicate = null
)
{
return RecursivelyConvertToNative_Enumerable(rootObject, parent, predicate).ToList();
}
/// <inheritdoc cref="RecursivelyConvertToNative_Enumerable"/>
/// <remarks>Calling this function will start a coroutine to complete later on the coroutine loop</remarks>
/// <returns>The started Coroutine</returns>
public Coroutine RecursivelyConvertToNative_Coroutine(
Base rootObject,
Transform? parent,
Predicate<TraversalContext>? predicate = null
)
{
return StartCoroutine(RecursivelyConvertToNative_Enumerable(rootObject, parent, predicate).GetEnumerator());
}
/// <summary>
/// Will recursively traverse the given <paramref name="rootObject"/> and convert convertable child objects
/// where the given <see cref="predicate"/>
/// </summary>
/// <param name="rootObject">The Speckle object to traverse and convert all convertable children</param>
/// <param name="parent">Optional parent <see cref="Transform"/> for the created root <see cref="GameObject"/>s</param>
/// <param name="predicate">A filter function to allow for selectively excluding certain objects from being converted</param>
/// <returns>An unevaluated <see cref="IEnumerable"/> of all created <see cref="GameObject"/>s</returns>
public IEnumerable<ConversionResult> RecursivelyConvertToNative_Enumerable(
Base rootObject,
Transform? parent,
Predicate<TraversalContext>? predicate = null)
{
var userPredicate = predicate ?? (_ => true);
var traversalFunc = DefaultTraversal.CreateBIMTraverseFunc(ConverterInstance);
var objectsToConvert = traversalFunc
.Traverse(rootObject)
.Where(x => ConverterInstance.CanConvertToNative(x.current))
.Where(x => userPredicate(x));
Dictionary<Base, GameObject?> created = new();
foreach (var conversionResult in ConvertTree(objectsToConvert, parent, created))
{
if (!isActiveAndEnabled) throw new InvalidOperationException($"Cannot convert objects while {GetType()} is disabled");
yield return conversionResult;
}
}
/// <summary>
/// Converts a objectTree (see <see cref="GraphTraversal"/>) to unevaluated enumerable.
/// As this enumerable is iterated through, each context <see cref="Base"/> object will be converted to <see cref="GameObject"/> (if successful)
/// or <see langword="null"/> if not.
/// </summary>
/// <remarks>
/// You may enumerate over multiple frames (e.g. coroutine) but you must ensure the output eventually gets fully enumerated (exactly once)
/// </remarks>
/// <param name="objectTree"></param>
/// <param name="parent"></param>
/// <param name="outCreatedObjects"></param>
/// <returns></returns>
protected IEnumerable<ConversionResult> ConvertTree(IEnumerable<TraversalContext> objectTree, Transform? parent, IDictionary<Base, GameObject?> outCreatedObjects)
{
InitializeAssetCache();
AssetCache.BeginWrite();
foreach (TraversalContext tc in objectTree)
{
ConversionResult result;
try
{
Transform? currentParent = GetParent(tc, outCreatedObjects) ?? parent;
var converted = ConvertToNative(tc.current, currentParent);
result = new ConversionResult(tc, converted);
outCreatedObjects.TryAdd(tc.current, result.converted);
}
catch (Exception ex)
{
result = new ConversionResult(tc, ex);
}
yield return result;
}
AssetCache.FinishWrite();
}
protected static Transform? GetParent(TraversalContext? tc, IDictionary<Base, GameObject?> createdObjects)
{
if (tc == null) return null; //We've reached the root object, and still not found a converted parent
if(createdObjects.TryGetValue(tc.current, out GameObject? p) && p != null)
return p.transform;
//Go one level up, and repeat!
return GetParent(tc.parent, createdObjects);
}
protected GameObject ConvertToNative(Base speckleObject, Transform? parentTransform)
{
GameObject? go = ConverterInstance.ConvertToNative(speckleObject) as GameObject;
if (go == null) throw new SpeckleException("Conversion Returned Null");
go.transform.SetParent(parentTransform, true);
//Set some common for all created GameObjects
//TODO add support for more unity specific props
if(go.name == "New Game Object" || string.IsNullOrWhiteSpace(go.name))
go.name = CoreUtils.GenerateObjectName(speckleObject);
if (speckleObject["physicsLayer"] is string layerName)
{
int layer = LayerMask.NameToLayer(layerName); //TODO: check how this can be interoperable with Unreal and Blender
if (layer > -1) go.layer = layer;
}
//if (baseObject["tag"] is string t) go.tag = t;
//if (baseObject["isStatic"] is bool isStatic) go.isStatic = isStatic;
return go;
}
#region deprecated conversion functions
[Obsolete("Use " + nameof(RecursivelyConvertToNative_Coroutine))]
public IEnumerator ConvertCoroutine(Base rootObject, Transform? parent, List<GameObject> outCreatedObjects)
=> ConvertCoroutine(rootObject, parent, outCreatedObjects,b => ConverterInstance.CanConvertToNative(b));
[Obsolete("Use " + nameof(RecursivelyConvertToNative_Coroutine))]
public IEnumerator ConvertCoroutine(Base rootObject, Transform? parent, List<GameObject> outCreatedObjects, Func<Base, bool> predicate)
{
foreach (string propertyName in GetPotentialChildren(rootObject))
@@ -29,21 +237,18 @@ namespace Speckle.ConnectorUnity.Components
/// <param name="o">The object to convert (<see cref="Base"/> or <see cref="List{T}"/> of)</param>
/// <param name="parent">Optional parent transform for the created root <see cref="GameObject"/>s</param>
/// <returns> A list of all created <see cref="GameObject"/>s</returns>
[Obsolete("Use " + nameof(RecursivelyConvertToNative_Sync))]
public virtual List<GameObject> RecursivelyConvertToNative(object? o, Transform? parent)
=> RecursivelyConvertToNative(o, parent, b => ConverterInstance.CanConvertToNative(b));
/// <inheritdoc cref="RecursivelyConvertToNative(object, Transform)"/>
/// <param name="predicate">A function to determine if an object should be converted</param>
[Obsolete("Use " + nameof(RecursivelyConvertToNative_Sync))]
public virtual List<GameObject> RecursivelyConvertToNative(object? o, Transform? parent, Func<Base, bool> predicate)
{
//Ensure we have A native cache
if (AssetCache.nativeCaches.Any(x => x == null))
{
AssetCache.nativeCaches = NativeCacheFactory.GetStandaloneCacheSetup();
}
InitializeAssetCache();
var createdGameObjects = new List<GameObject>();
ConverterInstance.SetContextDocument(AssetCache);
try
{
AssetCache.BeginWrite();
@@ -61,23 +266,17 @@ namespace Speckle.ConnectorUnity.Components
}
protected string[] namePropertyAliases = {"name", "Name"};
protected virtual string GenerateObjectName(Base baseObject)
private void InitializeAssetCache()
{
// 1. Use explicit name
foreach (var nameAlias in namePropertyAliases)
//Ensure we have A native cache
if (AssetCache.nativeCaches.Any(x => x == null))
{
string? s = baseObject[nameAlias] as string;
if (!string.IsNullOrWhiteSpace(s)) return s; //TODO any sanitization needed?
AssetCache.nativeCaches = NativeCacheFactory.GetStandaloneCacheSetup();
}
// 2. Use type + id as fallback name
// Only take the most derived type from the speckle type
string speckleType = baseObject.speckle_type.Split(':').Last();
return $"{speckleType} - {baseObject.id}";
ConverterInstance.SetContextDocument(AssetCache);
}
[Obsolete]
public virtual void RecurseTreeToNative(Base baseObject, Transform? parent, Func<Base, bool> predicate, IList<GameObject> outCreatedObjects)
{
object? converted = null;
@@ -96,7 +295,7 @@ namespace Speckle.ConnectorUnity.Components
//Set some common for all created GameObjects
//TODO add support for more unity specific props
if(go.name == "New Game Object" || string.IsNullOrWhiteSpace(go.name))
go.name = GenerateObjectName(baseObject);
go.name = CoreUtils.GenerateObjectName(baseObject);
//if (baseObject["tag"] is string t) go.tag = t;
if (baseObject["physicsLayer"] is string layerName)
{
@@ -117,6 +316,7 @@ namespace Speckle.ConnectorUnity.Components
}
[Obsolete]
private IEnumerable<string> GetPotentialChildren(Base baseObject)
{
return ConverterInstance.CanConvertToNative(baseObject)
@@ -124,44 +324,14 @@ namespace Speckle.ConnectorUnity.Components
: baseObject.GetMembers().Keys;
}
[Obsolete]
protected virtual void ConvertChild(object? value, Transform? parent, Func<Base, bool> predicate, IList<GameObject> outCreatedObjects)
{
if(value == null) return;
if(value.GetType().IsPrimitive) return;
if (value is string) return;
if(value is Base o)
foreach (Base b in GraphTraversal.TraverseMember(value))
{
RecurseTreeToNative(o, parent, predicate, outCreatedObjects);
}
else if (value is IDictionary dictionary)
{
foreach (object v in dictionary.Keys)
{
ConvertChild(v, parent, predicate, outCreatedObjects);
}
}
else if (value is IList collection)
{
foreach (object v in collection)
{
ConvertChild(v, parent, predicate, outCreatedObjects);
}
}
else if(!value.GetType().IsValueType) //don't want to output errors for structs
{
Debug.Log($"Unknown type {value.GetType()} found when traversing tree, will be safely ignored");
RecurseTreeToNative(b, parent, predicate, outCreatedObjects);
}
}
[Obsolete("Use RecursivelyConvertToNative instead")]
public GameObject ConvertRecursivelyToNative(Base @base, string name)
{
var parentObject = new GameObject(name);
RecursivelyConvertToNative(@base, parentObject.transform);
return parentObject;
}
#endregion
}
}
}
@@ -1,5 +1,6 @@
using Speckle.ConnectorUnity.Factories;
using Speckle.ConnectorUnity.NativeCache;
using Speckle.ConnectorUnity.Utils;
using Speckle.Core.Kits;
using Speckle.Core.Logging;
using UnityEngine;
@@ -18,7 +19,12 @@ namespace Speckle.ConnectorUnity.Components
[field: SerializeField]
public AggregateNativeCache AssetCache { get; set; }
private void Awake()
protected void Awake()
{
Init();
}
protected void Init()
{
Setup.Init(HostApplications.Unity.GetVersion(CoreUtils.GetHostAppVersion()), HostApplications.Unity.Slug);
@@ -30,4 +36,4 @@ namespace Speckle.ConnectorUnity.Components
}
}
}
}
}
@@ -1,16 +1,19 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Speckle.ConnectorUnity.Utils;
using Speckle.ConnectorUnity.Wrappers.Selection;
using Speckle.Core.Api;
using Speckle.Core.Credentials;
using Speckle.Core.Kits;
using Speckle.Core.Logging;
using Speckle.Core.Models;
using Speckle.Core.Models.GraphTraversal;
using Speckle.Core.Transports;
using UnityEngine;
using UnityEngine.Events;
@@ -37,134 +40,257 @@ namespace Speckle.ConnectorUnity.Components
public RecursiveConverter Converter { get; private set; }
#nullable enable
[Header("Events")]
[HideInInspector]
public CommitSelectionEvent OnCommitSelectionChange;
public CommitSelectionEvent OnCommitSelectionChange = new();
[HideInInspector]
public OperationProgressEvent OnReceiveProgressAction;
public OperationProgressEvent OnReceiveProgressAction = new();
[HideInInspector]
public ErrorActionEvent OnErrorAction;
public ErrorActionEvent OnErrorAction = new();
[HideInInspector]
public ChildrenCountHandler OnTotalChildrenCountKnown;
public ChildrenCountHandler OnTotalChildrenCountKnown = new();
[HideInInspector]
public ReceiveCompleteHandler OnComplete;
public ReceiveCompleteHandler OnComplete = new();
#nullable enable
protected internal CancellationTokenSource? CancellationTokenSource { get; private set; }
protected CancellationTokenSource? CancellationTokenSource { get; private set; }
public CancellationToken CancellationToken => CancellationTokenSource?.Token ?? default;
public bool IsReceiving => CancellationTokenSource != null;
//TODO runtime receiving
public IEnumerator ReceiveAndConvertRoutine(SpeckleReceiver speckleReceiver, string rootObjectName, Action<Base>? beforeConvertCallback = null)
/// <summary>
/// Cancels any current receive operations
/// </summary>
/// <remarks>
/// Note, this does not cancel any currently executing ConvertToNative, just the <see cref="Operations.Receive"/>.
/// </remarks>
/// <returns><see langword="true"/> if the cancellation request was made. <see langword="false"/> if there was no pending operation to cancel (see <see cref="IsReceiving"/>)</returns>
public bool Cancel()
{
Task<Base?> receiveOperation = Task.Run(ReceiveAsync);
if (CancellationTokenSource == null) return false;
CancellationTokenSource.Cancel();
return true;
}
/// <summary>
/// Receive the selected <see cref="Commit"/> object, and converts ToNative as children of <paramref name="parent"/>
/// </summary>
/// <param name="parent">Optional parent <see cref="Transform"/> for the created root <see cref="GameObject"/>s</param>
/// <param name="predicate">A filter function to allow for selectively excluding certain objects from being converted</param>
/// <remarks>function does not throw, instead calls <see cref="OnErrorAction"/>, and calls <see cref="OnComplete"/> upon completion</remarks>
/// <seealso cref="ReceiveAsync(System.Threading.CancellationToken)"/>
/// <seealso cref="RecursiveConverter.RecursivelyConvertToNative_Enumerable"/>
public IEnumerator ReceiveAndConvert_Routine(Transform? parent, Predicate<TraversalContext>? predicate = null)
{
if (IsReceiving)
{
OnErrorAction.Invoke("Failed to receive", new InvalidOperationException("A pending receive operation has already started"));
yield break;
}
CancellationTokenSource?.Dispose();
CancellationTokenSource = new();
// ReSharper disable once MethodSupportsCancellation
Task<Base> receiveOperation = Task.Run(async () =>
{
Base result = await ReceiveAsync(CancellationToken);
CancellationToken.ThrowIfCancellationRequested();
return result;
});
yield return new WaitUntil(() => receiveOperation.IsCompleted);
Base? b = receiveOperation.Result;
if (b == null) yield break;
if (receiveOperation.IsFaulted)
{
OnErrorAction.Invoke("Failed to receive", receiveOperation.Exception);
FinishOperation();
yield break;
}
Base b = receiveOperation.Result;
//TODO make routine break for each catergory/object
GameObject go = ConvertToNativeWithCategories(b, rootObjectName, beforeConvertCallback);
OnComplete.Invoke(go);
foreach (var _ in Converter.RecursivelyConvertToNative_Enumerable(b, parent, predicate))
{
yield return null;
}
OnComplete.Invoke(parent);
FinishOperation();
}
/// <inheritdoc cref="ReceiveAndConvert_Routine"/>
public async void ReceiveAndConvert_Async(Transform? parent, Predicate<TraversalContext>? predicate = null)
{
try
{
BeginOperation();
Base commitObject = await ReceiveAsync(CancellationToken).ConfigureAwait(true);
Converter.RecursivelyConvertToNative_Sync(commitObject, parent, predicate);
OnComplete.Invoke(parent);
}
catch (Exception ex)
{
OnErrorAction.Invoke("Failed to receive", ex);
}
finally
{
FinishOperation();
}
}
/// <summary>
/// Receives the selected commit object using async Task
/// </summary>
/// <returns>Awaitable commit object</returns>
/// <param name="cancellationToken"></param>
/// <exception cref="SpeckleException">thrown when selection is incomplete</exception>
public async Task<Base?> ReceiveAsync()
/// <remarks>
/// This function is safe to call concurrently from any threads.
/// For this reason we use <paramref name="cancellationToken"/> parameter, rather than use the <see cref="CancellationToken"/> property
/// <br/>
/// Additionally, <see cref="OnComplete"/> and <see cref="OnErrorAction"/> won't be called.
/// </remarks>
public async Task<Base> ReceiveAsync(CancellationToken cancellationToken)
{
CancellationTokenSource?.Cancel();
CancellationTokenSource?.Dispose();
CancellationTokenSource = new CancellationTokenSource();
if(!GetSelection(out Client? client, out Stream? stream, out Commit? commit, out string? error))
throw new SpeckleException(error);
return await ReceiveAsync(
token: CancellationTokenSource.Token,
client: client,
streamId: stream.id,
objectId: commit.referencedObject,
commitId: commit.id,
onProgressAction: dict => OnReceiveProgressAction.Invoke(dict),
onErrorAction: (m, e) => OnErrorAction.Invoke(m, e),
onTotalChildrenCountKnown: c => OnTotalChildrenCountKnown.Invoke(c)
);
cancellationToken.ThrowIfCancellationRequested();
ValidateSelection(out Client? client, out Stream? stream, out Commit? commit);
Base result = await ReceiveAsync(
client: client,
streamId: stream.id,
objectId: commit.referencedObject,
commit: commit,
onProgressAction: dict => OnReceiveProgressAction.Invoke(dict),
onTotalChildrenCountKnown: c => OnTotalChildrenCountKnown.Invoke(c),
cancellationToken: cancellationToken
)
.ConfigureAwait(false);
return result;
}
public void ValidateSelection(out Client client, out Stream stream, out Commit commit)
{
Client? selectedClient = Account.Client;
client = selectedClient ?? throw new InvalidOperationException("Invalid account selection");
Stream? selectedStream = Stream.Selected;
stream = selectedStream ?? throw new InvalidOperationException("Invalid stream selection");
Commit? selectedCommit = Commit.Selected;
commit = selectedCommit ?? throw new InvalidOperationException("Invalid commit selection");
}
/// <summary>
/// Starts a new receive operation with a <see cref="CancellationToken"/>
/// </summary>
/// <exception cref="InvalidOperationException">already receiving</exception>
protected internal CancellationToken BeginOperation()
{
if (IsReceiving) throw new InvalidOperationException("A pending receive operation has already started");
CancellationTokenSource?.Dispose();
CancellationTokenSource = new();
return CancellationTokenSource.Token;
}
protected internal void FinishOperation()
{
if (!IsReceiving) throw new InvalidOperationException("No pending operations to finish");
CancellationTokenSource!.Dispose();
CancellationTokenSource = null;
}
/// <summary>
/// Receives the requested <see cref="objectId"/> using async Task
/// </summary>
/// <param name="token"></param>
/// <param name="client"></param>
/// <param name="streamId"></param>
/// <param name="objectId"></param>
/// <param name="commitId"></param>
/// <param name="commit"></param>
/// <param name="onProgressAction"></param>
/// <param name="onErrorAction"></param>
/// <param name="onTotalChildrenCountKnown"></param>
/// <param name="cancellationToken"></param>
/// <exception cref="Exception">Throws various types of exceptions to indicate faliure</exception>
/// <returns></returns>
public static async Task<Base?> ReceiveAsync(CancellationToken token,
public static async Task<Base> ReceiveAsync(
Client client,
string streamId,
string objectId,
string? commitId,
Commit? commit,
Action<ConcurrentDictionary<string, int>>? onProgressAction = null,
Action<string, Exception>? onErrorAction = null,
Action<int>? onTotalChildrenCountKnown = null)
Action<int>? onTotalChildrenCountKnown = null,
CancellationToken cancellationToken = default)
{
ServerTransport transport = new ServerTransport(client.Account, streamId);
transport.CancellationToken = token;
Base? ret = null;
using var transport = new ServerTransportV2(client.Account, streamId);
transport.CancellationToken = cancellationToken;
cancellationToken.ThrowIfCancellationRequested();
Base? requestedObject = await Operations.Receive(
objectId: objectId,
cancellationToken: cancellationToken,
remoteTransport: transport,
onProgressAction: onProgressAction,
onErrorAction: (s, ex) =>
{
//Don't wrap cancellation exceptions!
if (ex is OperationCanceledException)
throw ex;
//HACK: Sometimes, the task was cancelled, and Operations.Receive doesn't fail in a reliable way. In this case, the exception is often simply a symptom of a cancel.
if (cancellationToken.IsCancellationRequested)
{
SpeckleLog.Logger.Warning(ex, "A task was cancelled, ignoring potentially symptomatic exception");
cancellationToken.ThrowIfCancellationRequested();
}
//Treat all operation errors as fatal
throw new SpeckleException($"Failed to receive requested object {objectId} from server: {s}", ex);
},
onTotalChildrenCountKnown: onTotalChildrenCountKnown,
disposeTransports: false
).ConfigureAwait(false);
Analytics.TrackEvent(client.Account, Analytics.Events.Receive, new Dictionary<string, object>()
{
{"mode", nameof(SpeckleReceiver)},
{"sourceHostApp", HostApplications.GetHostAppFromString(commit?.sourceApplication).Slug},
{"sourceHostAppVersion", commit?.sourceApplication ?? ""},
{"hostPlatform", Application.platform.ToString()},
{"isMultiplayer", commit != null && commit.authorId != client.Account.userInfo.id},
});
if (requestedObject == null)
throw new SpeckleException($"Operation {nameof(Operations.Receive)} returned null");
cancellationToken.ThrowIfCancellationRequested();
//Read receipt
try
{
Analytics.TrackEvent(client.Account, Analytics.Events.Receive);
token.ThrowIfCancellationRequested();
ret = await Operations.Receive(
objectId: objectId,
cancellationToken: token,
remoteTransport: transport,
onProgressAction: onProgressAction,
onErrorAction: onErrorAction,
onTotalChildrenCountKnown: onTotalChildrenCountKnown,
disposeTransports: true
);
token.ThrowIfCancellationRequested();
//Read receipt
try
await client.CommitReceived(cancellationToken, new CommitReceivedInput
{
await client.CommitReceived(token, new CommitReceivedInput
{
streamId = streamId,
commitId = commitId,
message = $"received commit from {Application.unityVersion}",
sourceApplication = HostApplications.Unity.GetVersion(CoreUtils.GetHostAppVersion())
});
}
catch (Exception e)
{
// Do nothing!
Debug.LogWarning($"Failed to send read receipt\n{e}");
}
streamId = streamId,
commitId = commit?.id,
message = $"received commit from {Application.unityVersion}",
sourceApplication = HostApplications.Unity.GetVersion(CoreUtils.GetHostAppVersion())
}).ConfigureAwait(false);
}
catch (Exception e)
{
onErrorAction?.Invoke(e.Message, e);
// Do nothing!
Debug.LogWarning($"Failed to send read receipt\n{e}");
}
finally
{
transport?.Dispose();
}
return ret;
return requestedObject;
}
/// <summary>
/// Helper method for using <see cref="RecursiveConverter"/>.
/// Creates blank GameObjects for each property/category of the root object.
@@ -173,6 +299,7 @@ namespace Speckle.ConnectorUnity.Components
/// <param name="rootObjectName">The name of the parent <see cref="GameObject"/> to create</param>
/// <param name="beforeConvertCallback">Callback for each object converted</param>
/// <returns>The created parent <see cref="GameObject"/></returns>
[Obsolete("Use " + nameof(RecursiveConverter) + " Now we have implemented support for " + nameof(Collection) + "s, receiving any collection is now the default behaviour")]
public GameObject ConvertToNativeWithCategories(Base @base, string rootObjectName,
Action<Base>? beforeConvertCallback)
{
@@ -205,7 +332,7 @@ namespace Speckle.ConnectorUnity.Components
return rootObject;
}
/// <summary>
///
/// </summary>
@@ -214,6 +341,7 @@ namespace Speckle.ConnectorUnity.Components
/// <param name="commit"></param>
/// <param name="error">error messages for </param>
/// <returns>true if selection is complete, as we are ready to receive</returns>
[Obsolete("Use " + nameof(ValidateSelection))]
public bool GetSelection(
[NotNullWhen(true)] out Client? client,
[NotNullWhen(true)] out Stream? stream,
@@ -252,22 +380,21 @@ namespace Speckle.ConnectorUnity.Components
/// </summary>
/// <param name="allAngles">when <see langword="true"/>, will fetch 360 degree preview image</param>
/// <param name="callback">Callback function to be called when the web request completes</param>
/// <returns><see langword="false"/> if <see cref="Account"/>, <see cref="Stream"/>, or <see cref="Commit"/> was <see langword="null"/></returns>
public bool GetPreviewImage(/*bool allAngles,*/ Action<Texture2D?> callback)
/// <returns>The executing <see cref="Coroutine"/> or <see langword="null"/> if <see cref="Account"/>, <see cref="Stream"/>, or <see cref="Commit"/> was <see langword="null"/></returns>
public Coroutine? GetPreviewImage(/*bool allAngles,*/ Action<Texture2D?> callback)
{
Account? account = Account.Selected;
if (account == null) return false;
if (account == null) return null;
string? streamId = Stream.Selected?.id;
if (streamId == null) return false;
if (streamId == null) return null;
string? commitId = Commit.Selected?.id;
if (commitId == null) return false;
if (commitId == null) return null;
string angles = /*allAngles ? "all" :*/ "";
string url = $"{account.serverInfo.url}/preview/{streamId}/commits/{commitId}/{angles}";
string authToken = account.token;
StartCoroutine(Utils.Utils.GetImageRoutine(url, authToken, callback));
return true;
return StartCoroutine(Utils.Utils.GetImageRoutine(url, authToken, callback));
}
#if UNITY_EDITOR
@@ -278,6 +405,8 @@ namespace Speckle.ConnectorUnity.Components
Application.OpenURL(url);
}
#endif
public string GetSelectedUrl()
{
string serverUrl = Account.Selected!.serverInfo.url;
@@ -293,13 +422,13 @@ namespace Speckle.ConnectorUnity.Components
public void Awake()
{
CoreUtils.SetupInit();
Converter = GetComponent<RecursiveConverter>();
Initialise(true);
}
protected void Initialise(bool forceRefresh = false)
{
CoreUtils.SetupInit();
Account ??= new AccountSelection();
Stream ??= new StreamSelection(Account);
Branch ??= new BranchSelection(Stream);
@@ -313,12 +442,16 @@ namespace Speckle.ConnectorUnity.Components
Account.RefreshOptions();
}
public void OnDestroy()
public void OnDisable()
{
CancellationTokenSource?.Cancel();
}
public void OnDestroy()
{
CancellationTokenSource?.Dispose();
}
public void OnBeforeSerialize()
{
//pass
@@ -327,12 +460,32 @@ namespace Speckle.ConnectorUnity.Components
{
Initialise();
}
#region Deprecated members
[Obsolete("use " + nameof(ReceiveAndConvertRoutine), true)]
public IEnumerator ReceiveAndConvertRoutine(SpeckleReceiver speckleReceiver, string rootObjectName, Action<Base>? beforeConvertCallback = null)
{
// ReSharper disable once MethodSupportsCancellation
Task<Base> receiveOperation = Task.Run(async () => await ReceiveAsync(CancellationToken));
yield return new WaitUntil(() => receiveOperation.IsCompleted);
Base? b = receiveOperation.Result;
if (b == null) yield break;
//NOTE: coroutine doesn't break for each catergory/object
GameObject go = ConvertToNativeWithCategories(b, rootObjectName, beforeConvertCallback);
}
#endregion
}
[Serializable] public sealed class CommitSelectionEvent : UnityEvent<Commit?> { }
[Serializable] public sealed class BranchSelectionEvent : UnityEvent<Branch?> { }
[Serializable] public sealed class ErrorActionEvent : UnityEvent<string, Exception> { }
[Serializable] public sealed class OperationProgressEvent : UnityEvent<ConcurrentDictionary<string, int>> { }
[Serializable] public sealed class ReceiveCompleteHandler : UnityEvent<GameObject> { }
[Serializable] public sealed class ReceiveCompleteHandler : UnityEvent<Transform?> { }
[Serializable] public sealed class ChildrenCountHandler : UnityEvent<int> { }
}
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using Speckle.ConnectorUnity.Utils;
using Speckle.ConnectorUnity.Wrappers.Selection;
using Speckle.Core.Api;
using Speckle.Core.Credentials;
@@ -84,7 +85,11 @@ namespace Speckle.ConnectorUnity.Components
onErrorAction: onErrorAction
);
Analytics.TrackEvent(client.Account, Analytics.Events.Send);
Analytics.TrackEvent(client.Account, Analytics.Events.Send, new Dictionary<string, object>()
{
{"mode", nameof(SpeckleSender)},
{"hostPlatform", Application.platform.ToString()},
});
if (createCommit && !cancellationToken.IsCancellationRequested)
{
@@ -179,13 +184,13 @@ namespace Speckle.ConnectorUnity.Components
public void Awake()
{
CoreUtils.SetupInit();
Initialise(true);
Converter = GetComponent<RecursiveConverter>();
}
protected void Initialise(bool forceRefresh = false)
{
CoreUtils.SetupInit();
Account ??= new AccountSelection();
Stream ??= new StreamSelection(Account);
Branch ??= new BranchSelection(Stream);
@@ -4,11 +4,13 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Objects.Other;
using Speckle.ConnectorUnity;
using Speckle.ConnectorUnity.NativeCache;
using Speckle.ConnectorUnity.Utils;
using Speckle.ConnectorUnity.Wrappers;
using Speckle.Core.Logging;
using Speckle.Core.Models;
using Speckle.Core.Models.GraphTraversal;
using UnityEditor;
using UnityEngine;
using Mesh = UnityEngine.Mesh;
@@ -211,29 +213,35 @@ namespace Objects.Converter.Unity
return sobject;
}
public GameObject? BlockToNative(BlockInstance block)
public GameObject InstanceToNative(Instance instance)
{
if (block.blockDefinition == null)
{
Debug.Log($"Skipping {typeof(BlockInstance)} {block.id}, block definition was null");
return null;
}
if (instance.definition == null) throw new ArgumentException("Definition was null", nameof(instance));
var defName = CoreUtils.GenerateObjectName(instance.definition);
// Check for existing converted object
if(LoadedAssets.TryGetObject(block.blockDefinition, out GameObject? existingGo))
if(LoadedAssets.TryGetObject(instance.definition, out GameObject? existingGo))
{
var go = InstantiateCopy(existingGo);
go.name = block.blockDefinition.name ?? "";
TransformToNativeTransform(go.transform, block.transform);
go.name = defName;
TransformToNativeTransform(go.transform, instance.transform);
return go;
}
// Convert the block definition
GameObject native = new GameObject(block.blockDefinition.name ?? "");
GameObject native = new(defName);
List<SMesh> meshes = new();
List<Base> others = new();
foreach (Base geo in block.blockDefinition.geometry)
var geometry = instance.definition is BlockDefinition b
? b.geometry
: GraphTraversal.TraverseMember(new[]
{
instance.definition["elements"] ?? instance.definition["@elements"],
instance.definition["displayValue"] ?? instance.definition["@displayValue"],
});
foreach (Base geo in geometry)
{
if (geo is SMesh m) meshes.Add(m);
else if (geo is IDisplayValue<List<SMesh>> s) meshes.AddRange(s.displayValue);
@@ -242,12 +250,12 @@ namespace Objects.Converter.Unity
if (meshes.Any())
{
if(!TryGetMeshFromCache(block.blockDefinition, meshes, out Mesh? nativeMesh, out _))
if(!TryGetMeshFromCache(instance.definition, meshes, out Mesh? nativeMesh, out _))
{
MeshToNativeMesh(meshes, out nativeMesh);
string name = AssetHelpers.GetObjectName(block.blockDefinition);
string name = CoreUtils.GenerateObjectName(instance.definition);
nativeMesh.name = name;
LoadedAssets.TrySaveObject(block.blockDefinition, nativeMesh);
LoadedAssets.TrySaveObject(instance.definition, nativeMesh);
}
var nativeMaterials = RenderMaterialsToNative(meshes);
native.SafeMeshSet(nativeMesh, nativeMaterials);
@@ -260,10 +268,16 @@ namespace Objects.Converter.Unity
c.transform.SetParent(native.transform, false);
}
LoadedAssets.TrySaveObject(block.blockDefinition, native);
LoadedAssets.TrySaveObject(instance.definition, native);
TransformToNativeTransform(native.transform, block.transform);
if (block["name"] is string instanceName) native.name = instanceName;
TransformToNativeTransform(native.transform, instance.transform);
var instanceName = CoreUtils.GetFriendlyObjectName(instance) != null
? CoreUtils.GenerateObjectName(instance)
: defName;
native.name = instanceName;
return native;
}
@@ -296,36 +310,34 @@ namespace Objects.Converter.Unity
/// <returns>Transformation matrix in Unity's coordinate system</returns>
public Matrix4x4 TransformToNativeMatrix(STransform speckleTransform)
{
double VD(int i) => speckleTransform.value[i];
float V(int i) => (float) VD(i);
var sf = Speckle.Core.Kits.Units.GetConversionFactor(speckleTransform.units, ModelUnits);
var smatrix = speckleTransform.matrix;
return new Matrix4x4
{
// Left (X -> X)
[0, 0] = V(0),
[2, 0] = V(4),
[1, 0] = V(8),
[3, 0] = V(12),
[0, 0] = smatrix.M11,
[2, 0] = smatrix.M21,
[1, 0] = smatrix.M31,
[3, 0] = smatrix.M41,
//Up (Z -> Y)
[0, 2] = V(1),
[2, 2] = V(5),
[1, 2] = V(9),
[3, 2] = V(13),
[0, 2] = smatrix.M12,
[2, 2] = smatrix.M22,
[1, 2] = smatrix.M32,
[3, 2] = smatrix.M42,
//Forwards (Y -> Z)
[0, 1] = V(2),
[2, 1] = V(6),
[1, 1] = V(10),
[3, 1] = V(14),
[0, 1] = smatrix.M13,
[2, 1] = smatrix.M23,
[1, 1] = smatrix.M33,
[3, 1] = smatrix.M43,
//Translation
[0, 3] = (float) (VD(3) * sf),
[2, 3] = (float) (VD(7) * sf),
[1, 3] = (float) (VD(11) * sf),
[3, 3] = V(15),
[0, 3] = (float) (smatrix.M14 * sf),
[2, 3] = (float) (smatrix.M24 * sf),
[1, 3] = (float) (smatrix.M34 * sf),
[3, 3] = smatrix.M44,
};
}
@@ -349,4 +361,4 @@ namespace Objects.Converter.Unity
}
}
}
}
@@ -6,6 +6,7 @@ using Speckle.ConnectorUnity.Utils;
using Objects.Other;
using Objects.Utils;
using Speckle.ConnectorUnity.NativeCache;
using Speckle.Core.Logging;
using Speckle.Core.Models;
using UnityEngine;
using UnityEngine.Rendering;
@@ -209,13 +210,9 @@ namespace Objects.Converter.Unity
/// <param name="element">The <see cref="Base"/> object being converted</param>
/// <param name="meshes">Collection of <see cref="Objects.Geometry.Mesh"/>es that shall be converted</param>
/// <returns>A <see cref="GameObject"/> with the converted <see cref="UnityEngine.Mesh"/>, <see cref="MeshFilter"/>, and <see cref="MeshRenderer"/></returns>
public GameObject? MeshesToNative(Base element, IReadOnlyCollection<SMesh> meshes)
public GameObject MeshesToNative(Base element, IReadOnlyCollection<SMesh> meshes)
{
if (!meshes.Any())
{
Debug.Log($"Skipping {element.GetType()} {element.id}, zero {typeof(SMesh)} provided");
return null;
}
if (!meshes.Any()) throw new ArgumentException("Expected at least one Mesh", nameof(meshes));
Material[] nativeMaterials = RenderMaterialsToNative(meshes);
@@ -223,7 +220,7 @@ namespace Objects.Converter.Unity
{
//Convert a new one
MeshToNativeMesh(meshes, out nativeMesh, out center);
string name = AssetHelpers.GetObjectName(element);
string name = CoreUtils.GenerateObjectName(element);
nativeMesh.name = name;
LoadedAssets.TrySaveObject(element, nativeMesh);
}
@@ -241,15 +238,12 @@ namespace Objects.Converter.Unity
/// </summary>
/// <param name="speckleMesh">Mesh to convert</param>
/// <returns></returns>
public GameObject? MeshToNative(SMesh speckleMesh)
public GameObject MeshToNative(SMesh speckleMesh)
{
if (speckleMesh.vertices.Count == 0 || speckleMesh.faces.Count == 0)
{
Debug.Log($"Skipping mesh {speckleMesh.id}, mesh data was empty");
return null;
}
GameObject? converted = MeshesToNative(speckleMesh, new[] {speckleMesh});
throw new ArgumentException("mesh data was empty", nameof(speckleMesh));
GameObject converted = MeshesToNative(speckleMesh, new[] {speckleMesh});
// Raw meshes shouldn't have dynamic props to attach
//if (converted != null) AttachSpeckleProperties(converted,speckleMesh.GetType(), GetProperties(speckleMesh, typeof(Mesh)));
@@ -262,7 +256,7 @@ namespace Objects.Converter.Unity
if (LoadedAssets.TryGetObject(element, out Mesh? existing))
{
nativeMesh = existing;
//todo This is pretty inefficient, having to the mesh data anyway just to get the center... eek
//todo This is pretty inefficient, having to convert the mesh data anyway just to get the center... eek
MeshDataToNative(meshes,
out List<Vector3> verts,
out _,
@@ -483,7 +477,7 @@ namespace Objects.Converter.Unity
var c = renderMaterial.diffuse.ToUnityColor();
mat.color = new Color(c.r, c.g, c.b, (float) renderMaterial.opacity);
mat.name = AssetHelpers.GetObjectName(renderMaterial);
mat.name = CoreUtils.GenerateObjectName(renderMaterial);
mat.SetFloat(Metallic, (float) renderMaterial.metalness);
mat.SetFloat(Glossiness, 1 - (float) renderMaterial.roughness);
if (renderMaterial.emissive != SColor.Black.ToArgb()) mat.EnableKeyword("_EMISSION");
@@ -5,6 +5,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Objects.BuiltElements;
using Objects.Organization;
using Objects.Other;
using Speckle.ConnectorUnity.Utils;
using Speckle.ConnectorUnity.NativeCache;
@@ -111,8 +112,10 @@ namespace Objects.Converter.Unity
return View3DToNative(v);
case Mesh o:
return MeshToNative(o);
case BlockInstance o:
return BlockToNative(o);
case Instance o:
return InstanceToNative(o);
case Collection c:
return CollectionToNative(c);
default:
//Object is not a raw geometry, convert it as display value element
@@ -183,6 +186,19 @@ namespace Objects.Converter.Unity
}
}
public GameObject CollectionToNative(Collection collection)
{
var name = collection.name ?? $"{collection.collectionType} -- {collection.applicationId ?? collection.id}";
var go = new GameObject(name);
AttachSpeckleProperties(go, collection.GetType(), GetProperties(collection));
if (name == "Rooms")
{
go.SetActive(false);
}
return go;
}
public bool CanConvertToNative(Base @object)
{
switch (@object)
@@ -195,13 +211,17 @@ namespace Objects.Converter.Unity
// return true;
// case Curve _:
// return true;
// case View3D _:
// case View2D:
// return false;
// case View _:
// return true;
case View2D _:
return false;
case Mesh _:
case Model:
return false; //This allows us to traverse older commits pre-collections
case Collection:
return true;
case BlockInstance _:
case Mesh:
return true;
case Instance:
return true;
default:
@@ -212,9 +232,9 @@ namespace Objects.Converter.Unity
if (@object[alias] is IList)
return true;
}
return false;
}
}
}
}
}
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 3e49710593731cc49b9d22a0ba82b5d1
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: b875f05888babdd4db73c70d39a33feb
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: c822f631fa258514f8b76cdcaacc1b36
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 5e6c835b7544a374095e58eddb5d2f1c
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: f4e83b55b28720a47a937b987aba6b02
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 49715c68e5dbf254ca4ca7bc11292537
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: c84f8458a24050a48b32654c570e7acc
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: f741667477576f444a8a566e2a1f4ce9
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 5f1430ebe15696242a6b437faa8b8666
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 6f16b872bea64534a87c7229fa49ac30
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 817747ee0314c9441bac48ea74d34d42
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 38b2c99acc4856c4186972b73c6fc332
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: a2d9231f2f78f0d4ea8786452ac71598
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: b8ebfa0955817084a887b7a704d43545
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 2c0b2a3a645b5844faa74f29d90cff65
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 3d1e392b0c6fd8f4a9e494675b787a9a
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: b0e1bc6a04c09e54188d8d8244b876e4
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: d3a7df0fa5bb87b43ac372cfefb11aca
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 3855fc1a60cef174fb322913390b6fd8
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: abe52d099c937594c8788655f4c2d181
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: d6653fb426e962248abae72e30dd2f59
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 1c5ef0b3d673fad46939969a3da4d610
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -7,59 +7,119 @@
"targets": {
".NETStandard,Version=v2.0": {},
".NETStandard,Version=v2.0/": {
"SpeckleCore2/2.1.0": {
"SpeckleCore2/2.0.999-local": {
"dependencies": {
"GraphQL.Client": "4.0.2",
"GraphQL.Client": "5.1.1",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "6.0.8",
"Microsoft.Data.Sqlite": "7.0.3",
"NETStandard.Library": "2.0.3",
"Sentry": "3.20.1",
"Speckle.Newtonsoft.Json": "12.0.3.1"
"Polly": "7.2.3",
"Polly.Contrib.WaitAndRetry": "1.1.1",
"Polly.Extensions.Http": "3.0.0",
"Sentry": "3.29.0",
"Sentry.Serilog": "3.29.0",
"Serilog": "2.12.0",
"Serilog.Enrichers.ClientInfo": "1.2.0",
"Serilog.Enrichers.GlobalLogContext": "3.0.0",
"Serilog.Exceptions": "8.4.0",
"Serilog.Sinks.Console": "4.1.0",
"Serilog.Sinks.Seq": "5.2.2",
"Speckle.Newtonsoft.Json": "13.0.2"
},
"runtime": {
"SpeckleCore2.dll": {}
}
},
"GraphQL.Client/4.0.2": {
"GraphQL.Client/5.1.1": {
"dependencies": {
"GraphQL.Client.Abstractions": "4.0.2",
"GraphQL.Client.Abstractions.Websocket": "4.0.2"
"GraphQL.Client.Abstractions": "5.1.1",
"GraphQL.Client.Abstractions.Websocket": "5.1.1",
"System.Reactive": "5.0.0"
},
"runtime": {
"lib/netstandard2.0/GraphQL.Client.dll": {
"assemblyVersion": "4.0.2.0",
"fileVersion": "4.0.2.0"
"assemblyVersion": "5.1.1.0",
"fileVersion": "5.1.1.0"
}
}
},
"GraphQL.Client.Abstractions/4.0.2": {
"GraphQL.Client.Abstractions/5.1.1": {
"dependencies": {
"GraphQL.Primitives": "4.0.2",
"System.Reactive": "4.3.2"
"GraphQL.Primitives": "5.1.1"
},
"runtime": {
"lib/netstandard2.0/GraphQL.Client.Abstractions.dll": {
"assemblyVersion": "4.0.2.0",
"fileVersion": "4.0.2.0"
"assemblyVersion": "5.1.1.0",
"fileVersion": "5.1.1.0"
}
}
},
"GraphQL.Client.Abstractions.Websocket/4.0.2": {
"GraphQL.Client.Abstractions.Websocket/5.1.1": {
"dependencies": {
"GraphQL.Client.Abstractions": "4.0.2"
"GraphQL.Client.Abstractions": "5.1.1"
},
"runtime": {
"lib/netstandard2.0/GraphQL.Client.Abstractions.Websocket.dll": {
"assemblyVersion": "4.0.2.0",
"fileVersion": "4.0.2.0"
"assemblyVersion": "5.1.1.0",
"fileVersion": "5.1.1.0"
}
}
},
"GraphQL.Primitives/4.0.2": {
"GraphQL.Primitives/5.1.1": {
"runtime": {
"lib/netstandard2.0/GraphQL.Primitives.dll": {
"assemblyVersion": "4.0.2.0",
"fileVersion": "4.0.2.0"
"assemblyVersion": "5.1.1.0",
"fileVersion": "5.1.1.0"
}
}
},
"Microsoft.AspNetCore.Http/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Http.Abstractions": "2.1.1",
"Microsoft.AspNetCore.WebUtilities": "2.1.1",
"Microsoft.Extensions.ObjectPool": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1",
"Microsoft.Net.Http.Headers": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Http.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
}
},
"Microsoft.AspNetCore.Http.Abstractions/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Http.Features": "2.1.1",
"System.Text.Encodings.Web": "5.0.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Http.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
}
},
"Microsoft.AspNetCore.Http.Features/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Primitives": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Http.Features.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
}
},
"Microsoft.AspNetCore.WebUtilities/2.1.1": {
"dependencies": {
"Microsoft.Net.Http.Headers": "2.1.1",
"System.Text.Encodings.Web": "5.0.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.WebUtilities.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
}
},
@@ -82,20 +142,72 @@
}
}
},
"Microsoft.Data.Sqlite/6.0.8": {
"Microsoft.Data.Sqlite/7.0.3": {
"dependencies": {
"Microsoft.Data.Sqlite.Core": "6.0.8",
"SQLitePCLRaw.bundle_e_sqlite3": "2.0.6"
"Microsoft.Data.Sqlite.Core": "7.0.3",
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
}
},
"Microsoft.Data.Sqlite.Core/6.0.8": {
"Microsoft.Data.Sqlite.Core/7.0.3": {
"dependencies": {
"SQLitePCLRaw.core": "2.0.6"
"SQLitePCLRaw.core": "2.1.4"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Data.Sqlite.dll": {
"assemblyVersion": "6.0.8.0",
"fileVersion": "6.0.822.36205"
"assemblyVersion": "7.0.3.0",
"fileVersion": "7.0.323.6302"
}
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions/2.1.1": {
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
}
},
"Microsoft.Extensions.ObjectPool/2.1.1": {
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.ObjectPool.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
}
},
"Microsoft.Extensions.Options/2.1.1": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.1",
"Microsoft.Extensions.Primitives": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Options.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
}
},
"Microsoft.Extensions.Primitives/2.1.1": {
"dependencies": {
"System.Memory": "4.5.4",
"System.Runtime.CompilerServices.Unsafe": "5.0.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Primitives.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
}
},
"Microsoft.Net.Http.Headers/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Primitives": "2.1.1",
"System.Buffers": "4.5.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Net.Http.Headers.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
}
},
@@ -106,7 +218,34 @@
"Microsoft.NETCore.Platforms": "1.1.0"
}
},
"Sentry/3.20.1": {
"Polly/7.2.3": {
"runtime": {
"lib/netstandard2.0/Polly.dll": {
"assemblyVersion": "7.0.0.0",
"fileVersion": "7.2.3.0"
}
}
},
"Polly.Contrib.WaitAndRetry/1.1.1": {
"runtime": {
"lib/netstandard2.0/Polly.Contrib.WaitAndRetry.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.1.1.0"
}
}
},
"Polly.Extensions.Http/3.0.0": {
"dependencies": {
"Polly": "7.2.3"
},
"runtime": {
"lib/netstandard2.0/Polly.Extensions.Http.dll": {
"assemblyVersion": "3.0.0.0",
"fileVersion": "3.0.0.0"
}
}
},
"Sentry/3.29.0": {
"dependencies": {
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"System.Buffers": "4.5.1",
@@ -116,52 +255,164 @@
},
"runtime": {
"lib/netstandard2.0/Sentry.dll": {
"assemblyVersion": "3.20.1.0",
"fileVersion": "3.20.1.0"
"assemblyVersion": "3.29.0.0",
"fileVersion": "3.29.0.0"
}
}
},
"Speckle.Newtonsoft.Json/12.0.3.1": {
"Sentry.Serilog/3.29.0": {
"dependencies": {
"Sentry": "3.29.0",
"Serilog": "2.12.0"
},
"runtime": {
"lib/netstandard2.0/Sentry.Serilog.dll": {
"assemblyVersion": "3.29.0.0",
"fileVersion": "3.29.0.0"
}
}
},
"Serilog/2.12.0": {
"runtime": {
"lib/netstandard2.0/Serilog.dll": {
"assemblyVersion": "2.0.0.0",
"fileVersion": "2.12.0.0"
}
}
},
"Serilog.Enrichers.ClientInfo/1.2.0": {
"dependencies": {
"Microsoft.AspNetCore.Http": "2.1.1",
"Serilog": "2.12.0"
},
"runtime": {
"lib/netstandard2.0/Serilog.Enrichers.ClientInfo.dll": {
"assemblyVersion": "0.0.0.0",
"fileVersion": "0.0.0.0"
}
}
},
"Serilog.Enrichers.GlobalLogContext/3.0.0": {
"dependencies": {
"Serilog": "2.12.0"
},
"runtime": {
"lib/netstandard2.0/Serilog.Enrichers.GlobalLogContext.dll": {
"assemblyVersion": "3.0.0.0",
"fileVersion": "3.0.0.0"
}
}
},
"Serilog.Exceptions/8.4.0": {
"dependencies": {
"Serilog": "2.12.0",
"System.Reflection.TypeExtensions": "4.7.0"
},
"runtime": {
"lib/netstandard2.0/Serilog.Exceptions.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.4.0.0"
}
}
},
"Serilog.Formatting.Compact/1.1.0": {
"dependencies": {
"Serilog": "2.12.0"
},
"runtime": {
"lib/netstandard2.0/Serilog.Formatting.Compact.dll": {
"assemblyVersion": "1.1.0.0",
"fileVersion": "1.1.0.0"
}
}
},
"Serilog.Sinks.Console/4.1.0": {
"dependencies": {
"Serilog": "2.12.0"
},
"runtime": {
"lib/netstandard2.0/Serilog.Sinks.Console.dll": {
"assemblyVersion": "4.1.0.0",
"fileVersion": "4.1.0.0"
}
}
},
"Serilog.Sinks.File/5.0.0": {
"dependencies": {
"Serilog": "2.12.0"
},
"runtime": {
"lib/netstandard2.0/Serilog.Sinks.File.dll": {
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.0.0"
}
}
},
"Serilog.Sinks.PeriodicBatching/3.1.0": {
"dependencies": {
"Serilog": "2.12.0"
},
"runtime": {
"lib/netstandard2.0/Serilog.Sinks.PeriodicBatching.dll": {
"assemblyVersion": "3.0.0.0",
"fileVersion": "3.1.0.0"
}
}
},
"Serilog.Sinks.Seq/5.2.2": {
"dependencies": {
"Serilog": "2.12.0",
"Serilog.Formatting.Compact": "1.1.0",
"Serilog.Sinks.File": "5.0.0",
"Serilog.Sinks.PeriodicBatching": "3.1.0"
},
"runtime": {
"lib/netstandard2.0/Serilog.Sinks.Seq.dll": {
"assemblyVersion": "5.2.2.0",
"fileVersion": "5.2.2.0"
}
}
},
"Speckle.Newtonsoft.Json/13.0.2": {
"runtime": {
"lib/netstandard2.0/Speckle.Newtonsoft.Json.dll": {
"assemblyVersion": "12.0.3.0",
"assemblyVersion": "11.0.0.0",
"fileVersion": "11.0.1.0"
}
}
},
"SQLitePCLRaw.bundle_e_sqlite3/2.0.6": {
"SQLitePCLRaw.bundle_e_sqlite3/2.1.4": {
"dependencies": {
"SQLitePCLRaw.core": "2.0.6",
"SQLitePCLRaw.lib.e_sqlite3": "2.0.6",
"SQLitePCLRaw.provider.e_sqlite3": "2.0.6"
"SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
"SQLitePCLRaw.provider.e_sqlite3": "2.1.4"
},
"runtime": {
"lib/netstandard2.0/SQLitePCLRaw.batteries_v2.dll": {
"assemblyVersion": "2.0.6.1341",
"fileVersion": "2.0.6.1341"
"assemblyVersion": "2.1.4.1835",
"fileVersion": "2.1.4.1835"
}
}
},
"SQLitePCLRaw.core/2.0.6": {
"SQLitePCLRaw.core/2.1.4": {
"dependencies": {
"System.Memory": "4.5.4"
},
"runtime": {
"lib/netstandard2.0/SQLitePCLRaw.core.dll": {
"assemblyVersion": "2.0.6.1341",
"fileVersion": "2.0.6.1341"
"assemblyVersion": "2.1.4.1835",
"fileVersion": "2.1.4.1835"
}
}
},
"SQLitePCLRaw.lib.e_sqlite3/2.0.6": {},
"SQLitePCLRaw.provider.e_sqlite3/2.0.6": {
"SQLitePCLRaw.lib.e_sqlite3/2.1.4": {},
"SQLitePCLRaw.provider.e_sqlite3/2.1.4": {
"dependencies": {
"SQLitePCLRaw.core": "2.0.6"
"SQLitePCLRaw.core": "2.1.4"
},
"runtime": {
"lib/netstandard2.0/SQLitePCLRaw.provider.e_sqlite3.dll": {
"assemblyVersion": "2.0.6.1341",
"fileVersion": "2.0.6.1341"
"assemblyVersion": "2.1.4.1835",
"fileVersion": "2.1.4.1835"
}
}
},
@@ -205,15 +456,15 @@
}
}
},
"System.Reactive/4.3.2": {
"System.Reactive/5.0.0": {
"dependencies": {
"System.Runtime.InteropServices.WindowsRuntime": "4.3.0",
"System.Threading.Tasks.Extensions": "4.5.4"
},
"runtime": {
"lib/netstandard2.0/System.Reactive.dll": {
"assemblyVersion": "4.3.0.0",
"fileVersion": "4.3.2.55399"
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.0.1"
}
}
},
@@ -228,6 +479,14 @@
}
}
},
"System.Reflection.TypeExtensions/4.7.0": {
"runtime": {
"lib/netstandard2.0/System.Reflection.TypeExtensions.dll": {
"assemblyVersion": "4.1.5.0",
"fileVersion": "4.700.19.56404"
}
}
},
"System.Runtime/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
@@ -296,38 +555,66 @@
}
},
"libraries": {
"SpeckleCore2/2.1.0": {
"SpeckleCore2/2.0.999-local": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"GraphQL.Client/4.0.2": {
"GraphQL.Client/5.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-EB/icQ7QWzCQzfT6yv8L6BAW+c7DrQuwIg/nNSguOQBMs2W7aaYMpEYidEZ4U2ao0CrT6gcCY0F8xz9hoB3Pvw==",
"path": "graphql.client/4.0.2",
"hashPath": "graphql.client.4.0.2.nupkg.sha512"
"sha512": "sha512-6bfM9qU4AMcFWm4BHd2M6LE5+rLtK47/+VRtypggwb9appC8sbF58ytVBVOKpqKhKpmZERfPLGJap8O/FH3w5w==",
"path": "graphql.client/5.1.1",
"hashPath": "graphql.client.5.1.1.nupkg.sha512"
},
"GraphQL.Client.Abstractions/4.0.2": {
"GraphQL.Client.Abstractions/5.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-zmtHtejUacIQHAdLEsetDX27mccX0R6MfEu32Ek4l6pprJe3zdtqx+UuWz3wSmrIaj05NLEe5FCHNTjhm3MnjA==",
"path": "graphql.client.abstractions/4.0.2",
"hashPath": "graphql.client.abstractions.4.0.2.nupkg.sha512"
"sha512": "sha512-/znG7Lcz3rzG9VSCq+V2ARb63c/uIs8idGOvXyltZ32Wy570GX/I8HNUIZ1yDThmQRJ5KOGSd9Mzk37lFg49rg==",
"path": "graphql.client.abstractions/5.1.1",
"hashPath": "graphql.client.abstractions.5.1.1.nupkg.sha512"
},
"GraphQL.Client.Abstractions.Websocket/4.0.2": {
"GraphQL.Client.Abstractions.Websocket/5.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-1JDpd1HgvytSWf7/v1TMJ1EXm6oVuga+lJWY9b9RtmGDjEtmFLxP1663/KLe5vTMzXRpxx3saOkkjikHhQOn3w==",
"path": "graphql.client.abstractions.websocket/4.0.2",
"hashPath": "graphql.client.abstractions.websocket.4.0.2.nupkg.sha512"
"sha512": "sha512-n1gU3GlqJ0jQceb/VEEr4c0D2vpQc5AtDwthK89+yX7VpzlhJKqE5B4RJwx//Jb33mKybfJioWwDgVfSOPAwdw==",
"path": "graphql.client.abstractions.websocket/5.1.1",
"hashPath": "graphql.client.abstractions.websocket.5.1.1.nupkg.sha512"
},
"GraphQL.Primitives/4.0.2": {
"GraphQL.Primitives/5.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-+E7WLhaBahp+gKmavi/X/mwVXZUIl+VjVA5MKyzSOf3Zzo8DJCxvjsfybmosIRXee4Xk2YQKA+bKlPVuf1MG8g==",
"path": "graphql.primitives/4.0.2",
"hashPath": "graphql.primitives.4.0.2.nupkg.sha512"
"sha512": "sha512-RlGNsv19gbz6sQwkzif9J6Jd148nuIg1kRQf2AFOLp5K00IA+pKMdJvHF5t5llDR52Rok46ynhJv/wg+ps9ZhQ==",
"path": "graphql.primitives/5.1.1",
"hashPath": "graphql.primitives.5.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Http/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-pPDcCW8spnyibK3krpxrOpaFHf5fjV6k1Hsl6gfh77N/8gRYlLU7MOQDUnjpEwdlHmtxwJKQJNxZqVQOmJGRUw==",
"path": "microsoft.aspnetcore.http/2.1.1",
"hashPath": "microsoft.aspnetcore.http.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Http.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-kQUEVOU4loc8CPSb2WoHFTESqwIa8Ik7ysCBfTwzHAd0moWovc9JQLmhDIHlYLjHbyexqZAlkq/FPRUZqokebw==",
"path": "microsoft.aspnetcore.http.abstractions/2.1.1",
"hashPath": "microsoft.aspnetcore.http.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Http.Features/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-VklZ7hWgSvHBcDtwYYkdMdI/adlf7ebxTZ9kdzAhX+gUs5jSHE9mZlTamdgf9miSsxc1QjNazHXTDJdVPZKKTw==",
"path": "microsoft.aspnetcore.http.features/2.1.1",
"hashPath": "microsoft.aspnetcore.http.features.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.WebUtilities/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-PGKIZt4+412Z/XPoSjvYu/QIbTxcAQuEFNoA1Pw8a9mgmO0ZhNBmfaNyhgXFf7Rq62kP0tT/2WXpxdcQhkFUPA==",
"path": "microsoft.aspnetcore.webutilities/2.1.1",
"hashPath": "microsoft.aspnetcore.webutilities.2.1.1.nupkg.sha512"
},
"Microsoft.Bcl.AsyncInterfaces/5.0.0": {
"type": "package",
@@ -343,19 +630,54 @@
"path": "microsoft.csharp/4.7.0",
"hashPath": "microsoft.csharp.4.7.0.nupkg.sha512"
},
"Microsoft.Data.Sqlite/6.0.8": {
"Microsoft.Data.Sqlite/7.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-oX2Ehhy1s/5CLaXRzajASHu2bAp87QrMqPzF3MjQlAm3alUwgmeIDdbm2Mp4i4BB2oxdujyeYCGcDnbew8mBdA==",
"path": "microsoft.data.sqlite/6.0.8",
"hashPath": "microsoft.data.sqlite.6.0.8.nupkg.sha512"
"sha512": "sha512-uumx0bb4FsN7ApP0ZoQDfSJi9c2Xen0PlXCT2BF27cM+yUMFzDEhqxR7/1/DV8ck4mYtL9yShBoOa7jeJ3736w==",
"path": "microsoft.data.sqlite/7.0.3",
"hashPath": "microsoft.data.sqlite.7.0.3.nupkg.sha512"
},
"Microsoft.Data.Sqlite.Core/6.0.8": {
"Microsoft.Data.Sqlite.Core/7.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ssJbtn9p7vXh3T4gi7g1Ir0bY4cJgVOU1MtTvnl4JvbLNmlq2q24SNK5jJHK/IPI37nhDqcPLHtfW40bscYU/Q==",
"path": "microsoft.data.sqlite.core/6.0.8",
"hashPath": "microsoft.data.sqlite.core.6.0.8.nupkg.sha512"
"sha512": "sha512-pCmzLLWTIrIv94o7JtQ1qcPD0oc1YNY9XvlO6/tOF9YCcUfDZ3Tx9Z//CM7hFnprduHFPekif7jteBc/sXQ31Q==",
"path": "microsoft.data.sqlite.core/7.0.3",
"hashPath": "microsoft.data.sqlite.core.7.0.3.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-MgYpU5cwZohUMKKg3sbPhvGG+eAZ/59E9UwPwlrUkyXU+PGzqwZg9yyQNjhxuAWmoNoFReoemeCku50prYSGzA==",
"path": "microsoft.extensions.dependencyinjection.abstractions/2.1.1",
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.ObjectPool/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-SErON45qh4ogDp6lr6UvVmFYW0FERihW+IQ+2JyFv1PUyWktcJytFaWH5zarufJvZwhci7Rf1IyGXr9pVEadTw==",
"path": "microsoft.extensions.objectpool/2.1.1",
"hashPath": "microsoft.extensions.objectpool.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Options/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-V7lXCU78lAbzaulCGFKojcCyG8RTJicEbiBkPJjFqiqXwndEBBIehdXRMWEVU3UtzQ1yDvphiWUL9th6/4gJ7w==",
"path": "microsoft.extensions.options/2.1.1",
"hashPath": "microsoft.extensions.options.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Primitives/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-scJ1GZNIxMmjpENh0UZ8XCQ6vzr/LzeF9WvEA51Ix2OQGAs9WPgPu8ABVUdvpKPLuor/t05gm6menJK3PwqOXg==",
"path": "microsoft.extensions.primitives/2.1.1",
"hashPath": "microsoft.extensions.primitives.2.1.1.nupkg.sha512"
},
"Microsoft.Net.Http.Headers/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-lPNIphl8b2EuhOE9dMH6EZDmu7pS882O+HMi5BJNsigxHaWlBrYxZHFZgE18cyaPp6SSZcTkKkuzfjV/RRQKlA==",
"path": "microsoft.net.http.headers/2.1.1",
"hashPath": "microsoft.net.http.headers.2.1.1.nupkg.sha512"
},
"Microsoft.NETCore.Platforms/1.1.0": {
"type": "package",
@@ -378,47 +700,138 @@
"path": "netstandard.library/2.0.3",
"hashPath": "netstandard.library.2.0.3.nupkg.sha512"
},
"Sentry/3.20.1": {
"Polly/7.2.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-SkI+CaRmdi5W3JA2plmJpjCQ+P49EuoCODmvrcYUGqeWMGwqa8DJWyeUDpso1DD82wYzbQ0RioSAoxG3nUhzjQ==",
"path": "sentry/3.20.1",
"hashPath": "sentry.3.20.1.nupkg.sha512"
"sha512": "sha512-DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ==",
"path": "polly/7.2.3",
"hashPath": "polly.7.2.3.nupkg.sha512"
},
"Speckle.Newtonsoft.Json/12.0.3.1": {
"Polly.Contrib.WaitAndRetry/1.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-yM+DdKzI++HY4FYbloGcPGQ0yrfSv5/a5Rd+iYuzj47ATRtb2M5oCEVcxM4Xum5EDq0BMwkIY/cw/DMlRrZFDA==",
"path": "speckle.newtonsoft.json/12.0.3.1",
"hashPath": "speckle.newtonsoft.json.12.0.3.1.nupkg.sha512"
"sha512": "sha512-1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA==",
"path": "polly.contrib.waitandretry/1.1.1",
"hashPath": "polly.contrib.waitandretry.1.1.1.nupkg.sha512"
},
"SQLitePCLRaw.bundle_e_sqlite3/2.0.6": {
"Polly.Extensions.Http/3.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-zssYqiaucyGArZfg74rJuzK0ewgZiidsRVrZTmP7JLNvK806gXg6PGA46XzoJGpNPPA5uRcumwvVp6YTYxtQ5w==",
"path": "sqlitepclraw.bundle_e_sqlite3/2.0.6",
"hashPath": "sqlitepclraw.bundle_e_sqlite3.2.0.6.nupkg.sha512"
"sha512": "sha512-drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
"path": "polly.extensions.http/3.0.0",
"hashPath": "polly.extensions.http.3.0.0.nupkg.sha512"
},
"SQLitePCLRaw.core/2.0.6": {
"Sentry/3.29.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Vh8n0dTvwXkCGur2WqQTITvk4BUO8i8h9ucSx3wwuaej3s2S6ZC0R7vqCTf9TfS/I4QkXO6g3W2YQIRFkOcijA==",
"path": "sqlitepclraw.core/2.0.6",
"hashPath": "sqlitepclraw.core.2.0.6.nupkg.sha512"
"sha512": "sha512-0AQbZte9ETORcrLj+gmzZcjbB3UwLl6KmdRVC9mcFfWTPftnSqVrgWDQHR70t2EYK5w6Y1pM8FAFyLDSJWvyRA==",
"path": "sentry/3.29.0",
"hashPath": "sentry.3.29.0.nupkg.sha512"
},
"SQLitePCLRaw.lib.e_sqlite3/2.0.6": {
"Sentry.Serilog/3.29.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-xlstskMKalKQl0H2uLNe0viBM6fvAGLWqKZUQ3twX5y1tSOZKe0+EbXopQKYdbjJytNGI6y5WSKjpI+kVr2Ckg==",
"path": "sqlitepclraw.lib.e_sqlite3/2.0.6",
"hashPath": "sqlitepclraw.lib.e_sqlite3.2.0.6.nupkg.sha512"
"sha512": "sha512-1g+x8fkoYe3/X6qH2F5hJ6eGkfhGqkMcib0P+dGH6lndnVseP+Lgx8HeO8zk3x3bkS2/GUEV7fn/QnFdh32R4A==",
"path": "sentry.serilog/3.29.0",
"hashPath": "sentry.serilog.3.29.0.nupkg.sha512"
},
"SQLitePCLRaw.provider.e_sqlite3/2.0.6": {
"Serilog/2.12.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-peXLJbhU+0clVBIPirihM1NoTBqw8ouBpcUsVMlcZ4k6fcL2hwgkctVB2Nt5VsbnOJcPspQL5xQK7QvLpxkMgg==",
"path": "sqlitepclraw.provider.e_sqlite3/2.0.6",
"hashPath": "sqlitepclraw.provider.e_sqlite3.2.0.6.nupkg.sha512"
"sha512": "sha512-xaiJLIdu6rYMKfQMYUZgTy8YK7SMZjB4Yk50C/u//Z4OsvxkUfSPJy4nknfvwAC34yr13q7kcyh4grbwhSxyZg==",
"path": "serilog/2.12.0",
"hashPath": "serilog.2.12.0.nupkg.sha512"
},
"Serilog.Enrichers.ClientInfo/1.2.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ZJx2eJQKX6+GxjZM9Y++7DPunR7Nizk9Vdq+BqMs/YPfW3Sv+qDm3PVC88srywJMDKfRaecHFWktBjw5F2pmoQ==",
"path": "serilog.enrichers.clientinfo/1.2.0",
"hashPath": "serilog.enrichers.clientinfo.1.2.0.nupkg.sha512"
},
"Serilog.Enrichers.GlobalLogContext/3.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-IIZcj5mAUVhIl/NTA+YI2KC+sPDzcwvs0ZMHH42jsPfl1a4LVX7ohVpw5UK+e3GxuV3Nv239Il5oM2peUIl44g==",
"path": "serilog.enrichers.globallogcontext/3.0.0",
"hashPath": "serilog.enrichers.globallogcontext.3.0.0.nupkg.sha512"
},
"Serilog.Exceptions/8.4.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-nc/+hUw3lsdo0zCj0KMIybAu7perMx79vu72w0za9Nsi6mWyNkGXxYxakAjWB7nEmYL6zdmhEQRB4oJ2ALUeug==",
"path": "serilog.exceptions/8.4.0",
"hashPath": "serilog.exceptions.8.4.0.nupkg.sha512"
},
"Serilog.Formatting.Compact/1.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-pNroKVjo+rDqlxNG5PXkRLpfSCuDOBY0ri6jp9PLe505ljqwhwZz8ospy2vWhQlFu5GkIesh3FcDs4n7sWZODA==",
"path": "serilog.formatting.compact/1.1.0",
"hashPath": "serilog.formatting.compact.1.1.0.nupkg.sha512"
},
"Serilog.Sinks.Console/4.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-K6N5q+5fetjnJPvCmkWOpJ/V8IEIoMIB1s86OzBrbxwTyHxdx3pmz4H+8+O/Dc/ftUX12DM1aynx/dDowkwzqg==",
"path": "serilog.sinks.console/4.1.0",
"hashPath": "serilog.sinks.console.4.1.0.nupkg.sha512"
},
"Serilog.Sinks.File/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-uwV5hdhWPwUH1szhO8PJpFiahqXmzPzJT/sOijH/kFgUx+cyoDTMM8MHD0adw9+Iem6itoibbUXHYslzXsLEAg==",
"path": "serilog.sinks.file/5.0.0",
"hashPath": "serilog.sinks.file.5.0.0.nupkg.sha512"
},
"Serilog.Sinks.PeriodicBatching/3.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-NDWR7m3PalVlGEq3rzoktrXikjFMLmpwF0HI4sowo8YDdU+gqPlTHlDQiOGxHfB0sTfjPA9JjA7ctKG9zqjGkw==",
"path": "serilog.sinks.periodicbatching/3.1.0",
"hashPath": "serilog.sinks.periodicbatching.3.1.0.nupkg.sha512"
},
"Serilog.Sinks.Seq/5.2.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-1Csmo5ua7NKUe0yXUx+zsRefjAniPWcXFhUXxXG8pwo0iMiw2gjn9SOkgYnnxbgWqmlGv236w0N/dHc2v5XwMg==",
"path": "serilog.sinks.seq/5.2.2",
"hashPath": "serilog.sinks.seq.5.2.2.nupkg.sha512"
},
"Speckle.Newtonsoft.Json/13.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA==",
"path": "speckle.newtonsoft.json/13.0.2",
"hashPath": "speckle.newtonsoft.json.13.0.2.nupkg.sha512"
},
"SQLitePCLRaw.bundle_e_sqlite3/2.1.4": {
"type": "package",
"serviceable": true,
"sha512": "sha512-EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
"path": "sqlitepclraw.bundle_e_sqlite3/2.1.4",
"hashPath": "sqlitepclraw.bundle_e_sqlite3.2.1.4.nupkg.sha512"
},
"SQLitePCLRaw.core/2.1.4": {
"type": "package",
"serviceable": true,
"sha512": "sha512-inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
"path": "sqlitepclraw.core/2.1.4",
"hashPath": "sqlitepclraw.core.2.1.4.nupkg.sha512"
},
"SQLitePCLRaw.lib.e_sqlite3/2.1.4": {
"type": "package",
"serviceable": true,
"sha512": "sha512-2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg==",
"path": "sqlitepclraw.lib.e_sqlite3/2.1.4",
"hashPath": "sqlitepclraw.lib.e_sqlite3.2.1.4.nupkg.sha512"
},
"SQLitePCLRaw.provider.e_sqlite3/2.1.4": {
"type": "package",
"serviceable": true,
"sha512": "sha512-CSlb5dUp1FMIkez9Iv5EXzpeq7rHryVNqwJMWnpq87j9zWZexaEMdisDktMsnnrzKM6ahNrsTkjqNodTBPBxtQ==",
"path": "sqlitepclraw.provider.e_sqlite3/2.1.4",
"hashPath": "sqlitepclraw.provider.e_sqlite3.2.1.4.nupkg.sha512"
},
"System.Buffers/4.5.1": {
"type": "package",
@@ -448,12 +861,12 @@
"path": "system.numerics.vectors/4.5.0",
"hashPath": "system.numerics.vectors.4.5.0.nupkg.sha512"
},
"System.Reactive/4.3.2": {
"System.Reactive/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-WhGkScPWxw2pp7UwRW8M1OvYZ3WUDPC2wJ0aiuaB4KRD3bt4wLkgHgYnOUu87WRhsurvv5LN0E63iWOEza2o8g==",
"path": "system.reactive/4.3.2",
"hashPath": "system.reactive.4.3.2.nupkg.sha512"
"sha512": "sha512-erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==",
"path": "system.reactive/5.0.0",
"hashPath": "system.reactive.5.0.0.nupkg.sha512"
},
"System.Reflection.Metadata/5.0.0": {
"type": "package",
@@ -462,6 +875,13 @@
"path": "system.reflection.metadata/5.0.0",
"hashPath": "system.reflection.metadata.5.0.0.nupkg.sha512"
},
"System.Reflection.TypeExtensions/4.7.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-VybpaOQQhqE6siHppMktjfGBw1GCwvCqiufqmP8F1nj7fTUNtW35LOEt3UZTEsECfo+ELAl/9o9nJx3U91i7vA==",
"path": "system.reflection.typeextensions/4.7.0",
"hashPath": "system.reflection.typeextensions.4.7.0.nupkg.sha512"
},
"System.Runtime/4.3.0": {
"type": "package",
"serviceable": true,
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ad66e20e6eccb2e4d9a01d9cb2525dec
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large Load Diff

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