using System; using System.Collections.Concurrent; using System.Diagnostics; using System.Threading.Tasks; using Cysharp.Threading.Tasks; using Speckle.Core.Api; using Speckle.Core.Models; using Speckle.Core.Transports; namespace Speckle.ConnectorUnity.Ops { public static partial class SpeckleOps { /// /// A unity friendly version of the Receive method from /// /// The client to use for interacting with the stream /// Stream ID to use /// Id of the object to receive /// Optional action to report progress values /// Optional action to notify about errors /// Optional action to get the total child count of the found object /// The unconverted base object public static async UniTask Receive( SpeckleUnityClient client, string streamId, string referenceObj, Action> onProgress = null, Action onError = null, Action onChildCount = null ) { var watch = Stopwatch.StartNew(); return await Receive(client, streamId, referenceObj, watch, onProgress, onError, onChildCount); } /// /// A unity friendly version of the Receive method from /// /// The client to use for interacting with the stream /// Stream ID to use /// Id of the object to receive /// A stopwatch for monitor time things /// Optional action to report progress values /// Optional action to notify about errors /// Optional action to get the total child count of the found object /// The unconverted base object public static async UniTask Receive( SpeckleUnityClient client, string streamId, string referenceObj, Stopwatch watch, Action> onProgress = null, Action onError = null, Action onChildCount = null ) { Base @base = null; watch ??= Stopwatch.StartNew(); SpeckleUnity.Console.Log($"{nameof(Receive)} intializing!"); if (client == null || !client.IsValid()) { SpeckleUnity.Console.Error($"{nameof(Receive)} cannot compelte due to an invalid {typeof(Client)}"); watch.Stop(); return null; } if (!streamId.Valid() || !referenceObj.Valid()) { SpeckleUnity.Console.Error( $"{nameof(Receive)} cannot compelte due to an invalid input." + $"\nstream id :{(streamId.Valid() ? streamId : "invalid")}" + $"\nobject id :{(referenceObj.Valid() ? referenceObj : "invalid")}"); watch.Stop(); return null; } // NOTE: could a unity transporter help with object creation? var transport = new ServerTransport(client.account, streamId); SpeckleUnity.Console.Log($"Starting recieve!\nstream id:{streamId} object id:{referenceObj}\n{watch.Elapsed}"); try { // NOTE: this is probably where a unity based transporter could be handy. For now this works just fine // only use Task with any client calls to speckle. Not worth the conversion await Task.Run(async () => { @base = await Operations.Receive(objectId: referenceObj, cancellationToken: client.token, remoteTransport: transport, onProgressAction: onProgress, onErrorAction: onError, onTotalChildrenCountKnown: onChildCount); SpeckleUnity.Console.Log($"Object Recieved:{@base}\nTotal time:{watch.Elapsed}"); }, client.token); } catch (Exception e) { SpeckleUnity.Console.Warn(e.Message); } finally { transport.Dispose(); watch.Stop(); SpeckleUnity.Console.Log($"{nameof(Receive)} command complete!\n{watch.Elapsed}"); await UniTask.Yield(); } return @base; } } }