public override void PostTraceReconciliation(Dictionary <Guid, List <ISerializable> > orphanedSerializables) { var orphanedIds = orphanedSerializables .SelectMany(kvp => kvp.Value) .Cast <SerializableId>() .Select(sid => sid.IntID).ToList(); if (!orphanedIds.Any()) { return; } if (IsTestMode) { DeleteOrphanedElements(orphanedIds, Logger); } else { // Delete all the orphans. IdlePromise.ExecuteOnIdleAsync( () => { DeleteOrphanedElements(orphanedIds, Logger); }); } }
private void Draw(IEnumerable <GeometryObject> geoms) { if (method == null) { method = GetTransientDisplayMethod(); if (method == null) { return; } } IdlePromise.ExecuteOnIdleAsync( () => { TransactionManager.Instance.EnsureInTransaction( DocumentManager.Instance.CurrentDBDocument); if (keeperId != ElementId.InvalidElementId && DocumentManager.Instance.CurrentDBDocument.GetElement(keeperId) != null) { DocumentManager.Instance.CurrentUIDocument.Document.Delete(keeperId); keeperId = ElementId.InvalidElementId; } var argsM = new object[4]; argsM[0] = DocumentManager.Instance.CurrentUIDocument.Document; argsM[1] = ElementId.InvalidElementId; argsM[2] = geoms; argsM[3] = ElementId.InvalidElementId; keeperId = (ElementId)method.Invoke(null, argsM); TransactionManager.Instance.ForceCloseTransaction(); }); }
private static void InitializeMaterials() { // Ensure that the current document has the needed materials // and graphic styles to support visualization in Revit. var mgr = MaterialsManager.Instance; IdlePromise.ExecuteOnIdleAsync(mgr.InitializeForActiveDocumentOnIdle); }
public override void ResetEngine(bool markNodesAsDirty = false) { IdlePromise.ExecuteOnIdleAsync(ResetEngineInternal); if (markNodesAsDirty) { Nodes.ForEach(n => n.RequiresRecalc = true); } }
protected override void OnClear() { IdlePromise.ExecuteOnIdleAsync( () => { TransactionManager.Instance.EnsureInTransaction( DocumentManager.Instance.CurrentDBDocument); if (keeperId != ElementId.InvalidElementId) { DocumentManager.Instance.CurrentUIDocument.Document.Delete(keeperId); keeperId = ElementId.InvalidElementId; } TransactionManager.Instance.ForceCloseTransaction(); }); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { HandleDebug(commandData); InitializeCore(commandData); try { #if ENABLE_DYNAMO_SCHEDULER extCommandData = commandData; commandData.Application.Idling += OnRevitIdleOnce; #else IdlePromise.ExecuteOnIdleAsync( delegate { // create core data models revitDynamoModel = InitializeCoreModel(commandData); dynamoViewModel = InitializeCoreViewModel(revitDynamoModel); // show the window InitializeCoreView().Show(); TryOpenWorkspaceInCommandData(commandData); SubscribeViewActivating(commandData); }); #endif // Disable the Dynamo button to prevent a re-run DynamoRevitApp.DynamoButton.Enabled = false; } catch (Exception ex) { // notify instrumentation InstrumentationLogger.LogException(ex); StabilityTracking.GetInstance().NotifyCrash(); MessageBox.Show(ex.ToString()); DynamoRevitApp.DynamoButton.Enabled = true; return(Result.Failed); } return(Result.Succeeded); }
public override void ShutDown(bool shutDownHost) { DisposeLogic.IsShuttingDown = true; OnShuttingDown(); base.ShutDown(shutDownHost); // unsubscribe events RevitServicesUpdater.UnRegisterAllChangeHooks(); UnsubscribeDocumentManagerEvents(); UnsubscribeRevitServicesUpdaterEvents(); UnsubscribeTransactionManagerEvents(); if (shutDownHost) { // this method cannot be called without Revit 2014 var exitCommand = RevitCommandId.LookupPostableCommandId(PostableCommand.ExitRevit); UIApplication uiapp = DocumentManager.Instance.CurrentUIApplication; IdlePromise.ExecuteOnIdleAsync( () => { if (uiapp.CanPostCommand(exitCommand)) { uiapp.PostCommand(exitCommand); } else { MessageBox.Show( "A command in progress prevented Dynamo from closing revit. Dynamo update will be cancelled."); } }); } }
/// <summary> /// This method reconciles the current state of the host with the current trace data, in revit's case /// deleting elements which have been orphaned and exist in trace but were not re-created /// </summary> /// <param name="orphanedSerializables"></param> public override void PostTraceReconciliation(Dictionary <Guid, List <ISerializable> > orphanedSerializables) { // because of multiSerialzableIDs some extra logic is // required to detect if one multiSerializableID is a subset of another, if thats the case we should not delete it. //get all the currentTraceData again RuntimeCore runtimeCore = null; if (this.EngineController != null && (this.EngineController.LiveRunnerCore != null)) { runtimeCore = this.EngineController.LiveRunnerRuntimeCore; } if (runtimeCore == null) { return; } //list of UUIDs we will remove from the list of orphans var toRemove = new List <String>(); //foreach orphaned ID check 2 cases: //1. an orphaned MultID is totally subset in one of the latest MultIDs //2. the latest IDS are subset in a MultID in the orphan list //in either of these cases we must remove the IDs from the orphan list so they are not deleted by accident foreach (var orphan in orphanedSerializables) { //if there are no multiSeriializables in the orphan then we can skip this orphan if (orphan.Value.OfType <MultipleSerializableId>().Count() == 0) { continue; } // Selecting all nodes that are either a DSFunction, // a DSVarArgFunction or a CodeBlockNodeModel into a list. var nodeGuids = this.Workspaces.Where(x => x.Guid == orphan.Key).First().Nodes.Where((n) => { return(n is DSFunction || (n is DSVarArgFunction) || (n is CodeBlockNodeModel)); }).Select((n) => n.GUID); //this is a list of all trace data for all nodes in the workspace of this orphan var nodeTraceDataList = runtimeCore.RuntimeData.GetCallsitesForNodes(nodeGuids, runtimeCore.DSExecutable); //check each callsite's traceData against the orphans foreach (var kvp in nodeTraceDataList) { foreach (var cs in kvp.Value) { var currentSerializables = cs.TraceData.SelectMany(td => td.RecursiveGetNestedData()); var currentStringIds = currentSerializables.OfType <MultipleSerializableId>().SelectMany(x => x.StringIDs).ToList(); //if the orphaned serializable exists in the currentTraceData as as subset in a MultiSerializableID toRemove.AddRange(orphan.Value.OfType <MultipleSerializableId>().Where(x => currentSerializables.OfType <MultipleSerializableId>().Any(y => x.isSubset(y))).SelectMany(x => x.StringIDs).ToList()); //Or if one of the callsites traceData is subset in an orphan toRemove.AddRange(currentStringIds.Intersect(orphan.Value.OfType <MultipleSerializableId>().SelectMany(y => y.StringIDs)).ToList()); //then remove it from the orphanList so we do not delete it later } } } var orphanedIds = new List <string>(); var serializables = orphanedSerializables .SelectMany(kvp => kvp.Value) .Where(x => x is ISerializable); orphanedIds.AddRange(serializables.Where(x => x is SerializableId). Cast <SerializableId>().Select(sid => sid.StringID)); orphanedIds.AddRange(serializables.Where(x => x is MultipleSerializableId). Cast <MultipleSerializableId>().SelectMany(sid => sid.StringIDs)); toRemove.ForEach(x => orphanedIds.Remove(x)); //the orphansIdsList is now free of elements that are subsets of newly created elements or Items that contain newly created elements if (!orphanedIds.Any()) { return; } if (IsTestMode) { DeleteOrphanedElements(orphanedIds, Logger); } else { // Delete all the orphans. IdlePromise.ExecuteOnIdleAsync( () => { DeleteOrphanedElements(orphanedIds, Logger); }); } }
protected override void OpenFileImpl(OpenFileCommand command) { IdlePromise.ExecuteOnIdleAsync(() => base.OpenFileImpl(command)); }
private void ReconcileHistoricalElements() { // Read the current run's trace data into a dictionary which matches // the layout of our historical element data. var traceData = EngineController.LiveRunnerCore.RuntimeData.GetTraceDataForNodes( CurrentWorkspace.Nodes.Select(n => n.GUID), EngineController.LiveRunnerCore.DSExecutable); var currentRunData = new Dictionary <Guid, List <int> >(); foreach (var kvp in traceData) { var idList = new List <int>(); currentRunData.Add(kvp.Key, idList); foreach (var serializables in kvp.Value.Select(DeserializeCallsiteData)) { idList.AddRange(serializables.Select(ser => ((SerializableId)ser).IntID)); } } // Compare the historical element data and the current run // data to see whether there are elements that had been // created by nodes previously, which were not created in // this run. Store the elements ids of all the elements that // can't be found in the orphans collection. var workspaceHistory = historicalElementData[CurrentWorkspace.Guid]; var orphanedIds = new List <int>(); foreach (var kvp in workspaceHistory) { var nodeGuid = kvp.Key; // If the current run doesn't have a key for // this guid, then all of these elements are // orphaned. if (!currentRunData.ContainsKey(nodeGuid)) { orphanedIds.AddRange(kvp.Value); continue; } var currentRunNodeGuids = currentRunData[nodeGuid]; // If the current run didn't create an element // in the current run, then add an orphan. orphanedIds.AddRange(kvp.Value.Where(id => !currentRunNodeGuids.Contains(id))); } // Delete all the orphans. IdlePromise.ExecuteOnIdleAsync( () => { var toDelete = new List <ElementId>(); foreach (var id in orphanedIds) { // Check whether the element is valid before attempting to delete. Element el; if (DocumentManager.Instance.CurrentDBDocument.TryGetElement(new ElementId(id), out el)) { toDelete.Add(el.Id); } } using (var trans = new Transaction(DocumentManager.Instance.CurrentDBDocument)) { trans.Start("Dynamo element reconciliation."); DocumentManager.Instance.CurrentDBDocument.Delete(toDelete); trans.Commit(); } }); Debug.WriteLine("ELEMENT RECONCILIATION: {0} elements were orphaned.", orphanedIds.Count); // When reconciliation is complete, wipe the historical data. // At this point, element binding is as up to date as it's going to get. historicalElementData.Remove(CurrentWorkspace.Guid); }