-
Notifications
You must be signed in to change notification settings - Fork 176
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto stash before checking out "origin/dui3/alpha"
- Loading branch information
Connor Ivy
committed
Jun 28, 2024
1 parent
0568a29
commit 487f7eb
Showing
68 changed files
with
1,119 additions
and
57 deletions.
There are no files selected for viewing
88 changes: 88 additions & 0 deletions
88
DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitReceiveBinding.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
using Speckle.Connectors.DUI.Bindings; | ||
using Speckle.Connectors.DUI.Bridge; | ||
using Speckle.Connectors.DUI.Models.Card; | ||
using Speckle.Connectors.DUI.Models; | ||
using Speckle.Connectors.Utils.Builders; | ||
using Speckle.Connectors.Utils.Cancellation; | ||
using Speckle.Connectors.Utils.Operations; | ||
using Speckle.Autofac.DependencyInjection; | ||
using Speckle.Connectors.Utils; | ||
|
||
namespace Speckle.Connectors.Revit.Bindings; | ||
|
||
internal class RevitReceiveBinding : IReceiveBinding | ||
{ | ||
public string Name => "receiveBinding"; | ||
public IBridge Parent { get; } | ||
|
||
private readonly CancellationManager _cancellationManager; | ||
private readonly DocumentModelStore _store; | ||
private readonly IUnitOfWorkFactory _unitOfWorkFactory; | ||
public ReceiveBindingUICommands Commands { get; } | ||
|
||
public RevitReceiveBinding( | ||
DocumentModelStore store, | ||
CancellationManager cancellationManager, | ||
IBridge parent, | ||
IUnitOfWorkFactory unitOfWorkFactory | ||
) | ||
{ | ||
Parent = parent; | ||
_store = store; | ||
_unitOfWorkFactory = unitOfWorkFactory; | ||
_cancellationManager = cancellationManager; | ||
Commands = new ReceiveBindingUICommands(parent); | ||
} | ||
|
||
public void CancelReceive(string modelCardId) => _cancellationManager.CancelOperation(modelCardId); | ||
|
||
public async Task Receive(string modelCardId) | ||
{ | ||
using var unitOfWork = _unitOfWorkFactory.Resolve<ReceiveOperation>(); | ||
try | ||
{ | ||
// Get receiver card | ||
if (_store.GetModelById(modelCardId) is not ReceiverModelCard modelCard) | ||
{ | ||
// Handle as GLOBAL ERROR at BrowserBridge | ||
throw new InvalidOperationException("No download model card was found."); | ||
} | ||
|
||
// Init cancellation token source -> Manager also cancel it if exist before | ||
CancellationTokenSource cts = _cancellationManager.InitCancellationTokenSource(modelCardId); | ||
|
||
// Receive host objects | ||
HostObjectBuilderResult conversionResults = await unitOfWork.Service | ||
.Execute( | ||
modelCard.AccountId.NotNull(), // POC: I hear -you are saying why we're passing them separately. Not sure pass the DUI3-> Connectors.DUI project dependency to the SDK-> Connector.Utils | ||
modelCard.ProjectId.NotNull(), | ||
modelCard.ProjectName.NotNull(), | ||
modelCard.ModelName.NotNull(), | ||
modelCard.SelectedVersionId.NotNull(), | ||
cts.Token, | ||
(status, progress) => OnSendOperationProgress(modelCardId, status, progress) | ||
) | ||
.ConfigureAwait(false); | ||
|
||
modelCard.BakedObjectIds = conversionResults.BakedObjectIds.ToList(); | ||
Commands.SetModelReceiveResult( | ||
modelCardId, | ||
conversionResults.BakedObjectIds, | ||
conversionResults.ConversionResults | ||
); | ||
} | ||
// Catch here specific exceptions if they related to model card. | ||
catch (OperationCanceledException) | ||
{ | ||
// SWALLOW -> UI handles it immediately, so we do not need to handle anything | ||
return; | ||
} | ||
} | ||
|
||
private void OnSendOperationProgress(string modelCardId, string status, double? progress) | ||
{ | ||
Commands.SetModelProgress(modelCardId, new ModelCardProgress(modelCardId, status, progress)); | ||
} | ||
|
||
public void CancelSend(string modelCardId) => _cancellationManager.CancelOperation(modelCardId); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
...onnectors/Revit/Speckle.Connectors.RevitShared/Operations/Receive/RevitContextAccessor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
using Revit.Async; | ||
using Speckle.Connectors.Utils.Operations; | ||
|
||
namespace Speckle.Connectors.Revit.Operations.Receive; | ||
|
||
internal class RevitContextAccessor : ISyncToThread | ||
{ | ||
public Task<T> RunOnThread<T>(Func<T> func) => RevitTask.RunAsync(func); | ||
} |
93 changes: 93 additions & 0 deletions
93
...nectors/Revit/Speckle.Connectors.RevitShared/Operations/Receive/RevitHostObjectBuilder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
using Speckle.Connectors.Utils.Builders; | ||
using Speckle.Connectors.Utils.Conversion; | ||
using Speckle.Converters.Common; | ||
using Speckle.Core.Logging; | ||
using Speckle.Core.Models.GraphTraversal; | ||
using Speckle.Core.Models; | ||
using Speckle.Converters.RevitShared.Helpers; | ||
|
||
namespace Speckle.Connectors.Revit.Operations.Receive; | ||
|
||
internal class RevitHostObjectBuilder : IHostObjectBuilder | ||
{ | ||
private readonly IRootToHostConverter _converter; | ||
private readonly IRevitConversionContextStack _contextStack; | ||
private readonly GraphTraversal _traverseFunction; | ||
private readonly TransactionManager _transactionManager; | ||
|
||
public RevitHostObjectBuilder( | ||
IRootToHostConverter converter, | ||
IRevitConversionContextStack contextStack, | ||
GraphTraversal traverseFunction, | ||
TransactionManager transactionManager | ||
) | ||
{ | ||
_converter = converter; | ||
_contextStack = contextStack; | ||
_traverseFunction = traverseFunction; | ||
_transactionManager = transactionManager; | ||
} | ||
|
||
public HostObjectBuilderResult Build( | ||
Base rootObject, | ||
string projectName, | ||
string modelName, | ||
Action<string, double?>? onOperationProgressed, | ||
CancellationToken cancellationToken | ||
) | ||
{ | ||
var objectsToConvert = _traverseFunction | ||
.TraverseWithProgress(rootObject, onOperationProgressed, cancellationToken) | ||
.Where(obj => obj.Current is not Collection); | ||
|
||
_transactionManager.StartTransactionGroup($"Received data from {projectName}"); | ||
|
||
var conversionResults = BakeObjects(objectsToConvert); | ||
|
||
_transactionManager.CommitTransactionGroup(); | ||
_transactionManager.Dispose(); | ||
|
||
return conversionResults; | ||
} | ||
|
||
// POC: Potentially refactor out into an IObjectBaker. | ||
private HostObjectBuilderResult BakeObjects(IEnumerable<TraversalContext> objectsGraph) | ||
{ | ||
var conversionResults = new List<ReceiveConversionResult>(); | ||
var bakedObjectIds = new List<string>(); | ||
|
||
foreach (TraversalContext tc in objectsGraph) | ||
{ | ||
try | ||
{ | ||
YieldToUiThread(); | ||
var result = _converter.Convert(tc.Current); | ||
} | ||
catch (Exception ex) when (!ex.IsFatal()) | ||
{ | ||
conversionResults.Add(new(Status.ERROR, tc.Current, null, null, ex)); | ||
} | ||
} | ||
|
||
return new(bakedObjectIds, conversionResults); | ||
} | ||
|
||
private DateTime _timerStarted = DateTime.MinValue; | ||
|
||
private void YieldToUiThread() | ||
{ | ||
var currentTime = DateTime.UtcNow; | ||
|
||
if (currentTime.Subtract(_timerStarted) < TimeSpan.FromSeconds(.15)) | ||
{ | ||
return; | ||
} | ||
|
||
System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke( | ||
() => { }, | ||
System.Windows.Threading.DispatcherPriority.Background | ||
); | ||
|
||
_timerStarted = currentTime; | ||
} | ||
} |
Oops, something went wrong.