From 1bc2d707686d2474c150868a5fe868ecdba89a74 Mon Sep 17 00:00:00 2001 From: Craig Long Date: Wed, 1 Nov 2023 09:33:21 -0400 Subject: [PATCH 1/2] First pass --- src/DynamoRevit/Models/RevitDynamoModel.cs | 97 ++++++-- .../AbstractAnalysisDisplay.cs | 60 +++-- .../AnalysisDisplay/FaceAnalysisDisplay.cs | 22 +- .../AnalysisDisplay/PointAnalysisDisplay.cs | 77 ------- .../RevitNodes/Elements/DirectShape.cs | 25 +- src/Libraries/RevitNodes/Elements/Level.cs | 24 +- .../Persistence/ElementBinder.cs | 213 ++++++++++-------- 7 files changed, 260 insertions(+), 258 deletions(-) diff --git a/src/DynamoRevit/Models/RevitDynamoModel.cs b/src/DynamoRevit/Models/RevitDynamoModel.cs index fb95862419..a0e02946ad 100644 --- a/src/DynamoRevit/Models/RevitDynamoModel.cs +++ b/src/DynamoRevit/Models/RevitDynamoModel.cs @@ -4,7 +4,6 @@ using System.Collections.Specialized; using System.Diagnostics; using System.Linq; -using System.Runtime.Serialization; using System.Windows.Forms; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Events; @@ -21,6 +20,7 @@ using Dynamo.Updates; using Dynamo.Utilities; using Greg; +using Newtonsoft.Json; using ProtoCore; using Revit.Elements; using RevitServices.Elements; @@ -244,7 +244,7 @@ private RevitDynamoModel(IRevitStartConfiguration configuration) : /// deleting elements which have been orphaned and exist in trace but were not re-created /// /// - public override void PostTraceReconciliation(Dictionary> orphanedSerializables) + public override void PostTraceReconciliation(Dictionary> 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. @@ -259,6 +259,9 @@ public override void PostTraceReconciliation(Dictionary(); + //list of stringIDs that we will track to remove. Initially will populate with StringIDs found in any MultipleSerializableId + //or SerializableId object in the trace + var orphanedIds = new List(); //foreach orphaned ID check 2 cases: //1. an orphaned MultID is totally subset in one of the latest MultIDs @@ -267,10 +270,18 @@ public override void PostTraceReconciliation(Dictionary().Count() == 0) + if (orphan.Value.Where(x => x.Contains("StringIDs") && x.Contains("IntIDs")).Count() == 0) { continue; } + + //else we need to process those multiSerializableIDs that exist in the orphan + var orphanMultipleSerializableIdObjects = GetAnyMultipleSerializableIDsFromListOfTraceData(orphan.Value); + var orphanStringIDs = orphanMultipleSerializableIdObjects.SelectMany(y => y.StringIDs); + + //Add to orphanedIds for later processing + orphanedIds.AddRange(orphanStringIDs); + // 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) => @@ -289,27 +300,23 @@ public override void PostTraceReconciliation(Dictionary td.RecursiveGetNestedData()); - var currentStringIds = currentSerializables.OfType().SelectMany(x => x.StringIDs).ToList(); + + var currentMultipleSerializableIdObject = GetAnyMultipleSerializableIDsFromListOfTraceData(currentSerializables); + + var currentStringIds = currentMultipleSerializableIdObject.SelectMany(x => x.StringIDs).ToList(); //if the orphaned serializable exists in the currentTraceData as as subset in a MultiSerializableID - toRemove.AddRange(orphan.Value.OfType().Where(x => currentSerializables.OfType().Any(y => x.isSubset(y))).SelectMany(x=>x.StringIDs).ToList()); + toRemove.AddRange(orphanMultipleSerializableIdObjects.Where(x => currentMultipleSerializableIdObject.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().SelectMany(y => y.StringIDs)).ToList()); + toRemove.AddRange(currentStringIds.Intersect(orphanStringIDs).ToList()); //then remove it from the orphanList so we do not delete it later } } } - - var orphanedIds = new List(); - var serializables = - orphanedSerializables - .SelectMany(kvp => kvp.Value) - .Where(x => x is ISerializable); - orphanedIds.AddRange(serializables.Where(x => x is SerializableId). - Cast().Select(sid => sid.StringID)); - orphanedIds.AddRange(serializables.Where(x => x is MultipleSerializableId). - Cast().SelectMany(sid => sid.StringIDs)); + //Now we find and add any StringIDs from SerializableID objects pressent in the orphan cachne + var stringIDsFromSerializeIDs = GetAnyStringIDsFromSerializableIDsPressentInOrhpanDictionary(orphanedSerializables); + orphanedIds.AddRange(stringIDsFromSerializeIDs); 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 @@ -332,6 +339,64 @@ public override void PostTraceReconciliation(Dictionary GetAnyMultipleSerializableIDsFromListOfTraceData(IEnumerable currentSerializables) + { + var anyMultipleSerializableId = new List(); + if (currentSerializables == null) + return anyMultipleSerializableId; + + foreach(var currentSerializable in currentSerializables) + { + if(currentSerializable == null) continue; + + MultipleSerializableId multi = null; + try + { + multi = JsonConvert.DeserializeObject(currentSerializable); + } + catch + { + //do nothing + } + + if (multi != null) + anyMultipleSerializableId.Add(multi); + } + + return anyMultipleSerializableId; + } + + private List GetAnyStringIDsFromSerializableIDsPressentInOrhpanDictionary(Dictionary> orphanedSerializables) + { + var allStringIDs = new List(); + + if (orphanedSerializables == null) + return allStringIDs; + + foreach (var keyValuePair in orphanedSerializables) + { + foreach (var serializableString in keyValuePair.Value) + { + if (serializableString == null) continue; + + SerializableId serializableObj = null; + try + { + serializableObj = JsonConvert.DeserializeObject(serializableString); + } + catch + { + //do nothing + } + + if (serializableObj != null) + allStringIDs.Add(serializableObj.StringID); + } + } + + return allStringIDs; + } + private static void DeleteOrphanedElements(IEnumerable orphanedIds, ILogger logger) { var toDelete = new List(); diff --git a/src/Libraries/RevitNodes/AnalysisDisplay/AbstractAnalysisDisplay.cs b/src/Libraries/RevitNodes/AnalysisDisplay/AbstractAnalysisDisplay.cs index 363c92eb35..079ee4b04a 100644 --- a/src/Libraries/RevitNodes/AnalysisDisplay/AbstractAnalysisDisplay.cs +++ b/src/Libraries/RevitNodes/AnalysisDisplay/AbstractAnalysisDisplay.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; using Autodesk.DesignScript.Runtime; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Analysis; using DynamoUnits; +using Newtonsoft.Json; using RevitServices.Elements; using RevitServices.Persistence; using RevitServices.Transactions; @@ -17,16 +17,15 @@ namespace Revit.AnalysisDisplay /// support serialization. /// [SupressImportIntoVM] - [Serializable] - public class SpmPrimitiveIdPair : ISerializable + public class SpmPrimitiveIdPair { public long SpatialFieldManagerID { get; set; } public List PrimitiveIds { get; set; } - - public void GetObjectData(SerializationInfo info, StreamingContext context) + + public SpmPrimitiveIdPair(long spatialFieldManagerID, List primitiveIds) { - info.AddValue("SpatialFieldManagerID", SpatialFieldManagerID, typeof(long)); - info.AddValue("PrimitiveIds", PrimitiveIds, typeof(List)); + SpatialFieldManagerID = spatialFieldManagerID; + PrimitiveIds = primitiveIds; } public SpmPrimitiveIdPair() @@ -34,40 +33,25 @@ public SpmPrimitiveIdPair() SpatialFieldManagerID = long.MinValue; PrimitiveIds = new List(); } - - public SpmPrimitiveIdPair(SerializationInfo info, StreamingContext context) - { - SpatialFieldManagerID = (long) info.GetValue("SpatialFieldManagerID", typeof (long)); - PrimitiveIds = - (List) - info.GetValue("PrimitiveIds", typeof(List)); - } } [SupressImportIntoVM] - [Serializable] - public class SpmRefPrimitiveIdListPair : ISerializable + public class SpmRefPrimitiveIdListPair { public long SpatialFieldManagerID { get; set; } public Dictionary RefIdPairs { get; set; } - public void GetObjectData(SerializationInfo info, StreamingContext context) + + public SpmRefPrimitiveIdListPair(long spatialFieldManagerID, Dictionary refIdPairs) { - info.AddValue("SpatialFieldManagerID", SpatialFieldManagerID, typeof(long)); - info.AddValue("ReferencePrimitiveIds", RefIdPairs, typeof(Dictionary)); + SpatialFieldManagerID = spatialFieldManagerID; + RefIdPairs = refIdPairs; } + public SpmRefPrimitiveIdListPair() { SpatialFieldManagerID = long.MinValue; RefIdPairs = new Dictionary(); } - - public SpmRefPrimitiveIdListPair(SerializationInfo info, StreamingContext context) - { - SpatialFieldManagerID = (long)info.GetValue("SpatialFieldManagerID", typeof(long)); - RefIdPairs = - (Dictionary) - info.GetValue("ReferencePrimitiveIds", typeof(Dictionary)); - } } /// @@ -240,11 +224,21 @@ void IDisposable.Dispose() protected Tuple> GetElementAndPrimitiveIdFromTrace() { // This is a provisional implementation until we can store both items in trace - var id = ElementBinder.GetRawDataFromTrace(); - if (id == null) + var traceString = ElementBinder.GetRawDataFromTrace(); + + if (String.IsNullOrEmpty(traceString)) return null; - var idPair = id as SpmPrimitiveIdPair; + SpmPrimitiveIdPair idPair = null; + try + { + idPair = JsonConvert.DeserializeObject(traceString); + } + catch + { + //do nothing + } + if (idPair == null) return null; @@ -277,7 +271,9 @@ protected void SetElementAndPrimitiveIdsForTrace(SpatialFieldManager manager, Li SpatialFieldManagerID = manager.Id.Value, PrimitiveIds = primitiveIds }; - ElementBinder.SetRawDataForTrace(idPair); + + var serializedTraceData = JsonConvert.SerializeObject(idPair); + ElementBinder.SetRawDataForTrace(serializedTraceData); } /// diff --git a/src/Libraries/RevitNodes/AnalysisDisplay/FaceAnalysisDisplay.cs b/src/Libraries/RevitNodes/AnalysisDisplay/FaceAnalysisDisplay.cs index 4d1b1c4ab9..05536d593e 100644 --- a/src/Libraries/RevitNodes/AnalysisDisplay/FaceAnalysisDisplay.cs +++ b/src/Libraries/RevitNodes/AnalysisDisplay/FaceAnalysisDisplay.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; using Analysis; using Dynamo.Graph.Nodes; using Autodesk.DesignScript.Runtime; @@ -14,6 +13,7 @@ using Surface = Autodesk.DesignScript.Geometry.Surface; using UV = Autodesk.Revit.DB.UV; using View = Revit.Elements.Views.View; +using Newtonsoft.Json; namespace Revit.AnalysisDisplay { @@ -278,11 +278,21 @@ public static FaceAnalysisDisplay ByViewAndFaceAnalysisData( protected Tuple> GetElementAndRefPrimitiveIdFromTrace() { // This is a provisional implementation until we can store both items in trace - var id = ElementBinder.GetRawDataFromTrace(); - if (id == null) + var traceString = ElementBinder.GetRawDataFromTrace(); + + if (String.IsNullOrEmpty(traceString)) return null; - var idPair = id as SpmRefPrimitiveIdListPair; + SpmRefPrimitiveIdListPair idPair = null; + try + { + idPair = JsonConvert.DeserializeObject(traceString); + } + catch + { + //do nothing + } + if (idPair == null) return null; @@ -315,7 +325,9 @@ protected void SetElementAndRefPrimitiveIdsForTrace(SpatialFieldManager manager, SpatialFieldManagerID = manager.Id.Value, RefIdPairs = keyValues }; - ElementBinder.SetRawDataForTrace(idPair); + + var serializedTraceData = JsonConvert.SerializeObject(idPair); + ElementBinder.SetRawDataForTrace(serializedTraceData); } protected void SetElementAndRefPrimitiveIdsForTrace() diff --git a/src/Libraries/RevitNodes/AnalysisDisplay/PointAnalysisDisplay.cs b/src/Libraries/RevitNodes/AnalysisDisplay/PointAnalysisDisplay.cs index c47c64a8bd..b732af0c7e 100644 --- a/src/Libraries/RevitNodes/AnalysisDisplay/PointAnalysisDisplay.cs +++ b/src/Libraries/RevitNodes/AnalysisDisplay/PointAnalysisDisplay.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; using Analysis; using Dynamo.Graph.Nodes; using Autodesk.DesignScript.Runtime; @@ -16,44 +15,6 @@ namespace Revit.AnalysisDisplay { - [SupressImportIntoVM] - [Serializable] - [Obsolete("Please use Revit.AnalysisDisplay.SpmPrimitiveIdPair instead")] - public class SpmPrimitiveIdListPair : ISerializable - { - public long SpatialFieldManagerID { get; set; } - public List PrimitiveIDs { get; set; } - - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("SpatialFieldManagerID", SpatialFieldManagerID, typeof(long)); - info.AddValue("PrimitiveIDCount", PrimitiveIDs.Count, typeof(int)); - foreach (var id in PrimitiveIDs) - { - info.AddValue("ID", id, typeof(int)); - } - } - - public SpmPrimitiveIdListPair() - { - SpatialFieldManagerID = long.MinValue; - PrimitiveIDs = new List(); - } - - public SpmPrimitiveIdListPair(SerializationInfo info, StreamingContext context) - { - SpatialFieldManagerID = (long)info.GetValue("SpatialFieldManagerID", typeof(long)); - - int count = (int)info.GetValue("PrimitiveIDCount", typeof(int)); - PrimitiveIDs = new List(); - for (int i = 0; i < count; ++i) - { - var id = (int)info.GetValue("ID", typeof(int)); - PrimitiveIDs.Add(id); - } - } - } - /// /// A Revit Point Analysis Display /// @@ -244,44 +205,6 @@ public static PointAnalysisDisplay ByViewAndPointAnalysisData(View view, } #endregion - - [Obsolete("Please use Revit.AnalysisDisplay.AbstractAnalysisDisplay instead")] - protected Tuple> GetElementAndPrimitiveIdListFromTrace() - { - // This is a provisional implementation until we can store both items in trace - var id = ElementBinder.GetRawDataFromTrace(); - if (id == null) - return null; - - var idPair = id as SpmPrimitiveIdListPair; - if (idPair == null) - return null; - - var primitiveIds = idPair.PrimitiveIDs; - var sfmId = idPair.SpatialFieldManagerID; - - SpatialFieldManager sfm = null; - - // if we can't get the sfm, return null - if (!Document.TryGetElement(new ElementId(sfmId), out sfm)) return null; - - return new Tuple>(sfm, primitiveIds); - } - [Obsolete("Please use Revit.AnalysisDisplay.AbstractAnalysisDisplay.SetElementAndPrimitiveIdsForTrace.GetElementAndPrimitiveIdFromTrace instead")] - protected void SetElementAndPrimitiveIdListTrace(SpatialFieldManager manager, List primitiveIds) - { - if (manager == null) - { - throw new Exception(); - } - - var idPair = new SpmPrimitiveIdListPair - { - SpatialFieldManagerID = manager.Id.Value, - PrimitiveIDs = primitiveIds - }; - ElementBinder.SetRawDataForTrace(idPair); - } } } diff --git a/src/Libraries/RevitNodes/Elements/DirectShape.cs b/src/Libraries/RevitNodes/Elements/DirectShape.cs index 5cbe4428a6..3b8d2bd6b9 100644 --- a/src/Libraries/RevitNodes/Elements/DirectShape.cs +++ b/src/Libraries/RevitNodes/Elements/DirectShape.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using System.Runtime.Serialization; using Autodesk.DesignScript.Geometry; using Autodesk.DesignScript.Runtime; using Autodesk.Revit.DB; +using Newtonsoft.Json; using Revit.GeometryConversion; using RevitServices.Materials; using RevitServices.Persistence; @@ -18,20 +18,11 @@ namespace Revit.Elements /// and DocumentEvents continue to function for DirectShapes. /// [SupressImportIntoVM] - [Serializable] public class DirectShapeState : SerializableId { public string syncId { get; set; } public long materialId { get; set; } - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - - info.AddValue("syncId", syncId, typeof(string)); - info.AddValue("materialId", materialId, typeof(int)); - } - public DirectShapeState(DirectShape ds, string syncId, ElementId materialId) : base() { @@ -40,13 +31,6 @@ public DirectShapeState(DirectShape ds, string syncId, ElementId materialId) : this.syncId = syncId; this.materialId = materialId.Value; } - - public DirectShapeState(SerializationInfo info, StreamingContext context) : - base(info, context) - { - syncId = (string)info.GetValue("syncId", typeof(string)); - materialId = (int)info.GetValue("materialId", typeof(int)); - } } /// @@ -173,7 +157,8 @@ private void InitDirectShape(DesignScriptEntity shapeReference, shapeReference.Tags.AddTag(this.InternalElementId.ToString(), traceData); TransactionManager.Instance.TransactionTaskDone(); - ElementBinder.SetRawDataForTrace(traceData); + var serializedTraceData = JsonConvert.SerializeObject(traceData); + ElementBinder.SetRawDataForTrace(serializedTraceData); } @@ -303,7 +288,9 @@ private void InternalSetShape(DesignScriptEntity shapeReference, ElementId mater //update the value in trace, since we had to modify the geometry we need a new syncId var updatedTraceData = new DirectShapeState(this, Guid.NewGuid().ToString(), materialId); - ElementBinder.SetRawDataForTrace(updatedTraceData); + + var serializedTraceData = JsonConvert.SerializeObject(updatedTraceData); + ElementBinder.SetRawDataForTrace(serializedTraceData); //place new values in the tags dict if (shapeReference.Tags.LookupTag(this.InternalElementId.ToString()) == null) { diff --git a/src/Libraries/RevitNodes/Elements/Level.cs b/src/Libraries/RevitNodes/Elements/Level.cs index 4c0e1316de..94d93688a9 100644 --- a/src/Libraries/RevitNodes/Elements/Level.cs +++ b/src/Libraries/RevitNodes/Elements/Level.cs @@ -1,9 +1,9 @@ using System; using System.Linq; -using System.Runtime.Serialization; using Autodesk.DesignScript.Runtime; using Autodesk.Revit.DB; using DynamoUnits; +using Newtonsoft.Json; using Revit.Elements.InternalUtilities; using Revit.GeometryConversion; using RevitServices.Persistence; @@ -17,18 +17,10 @@ namespace Revit.Elements /// it's used to keep track of what the user wanted to set the name of the level to /// [SupressImportIntoVM] - [Serializable] public class LevelTraceData : SerializableId { public string InputName { get; set; } - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - - info.AddValue("inputName", InputName, typeof(string)); - } - public LevelTraceData(Level lev, string inputName) : base() { @@ -36,13 +28,6 @@ public LevelTraceData(Level lev, string inputName) : this.StringID = lev.UniqueId; this.InputName = inputName; } - - public LevelTraceData(SerializationInfo info, StreamingContext context) : - base(info, context) - { - InputName = (string)info.GetValue("inputName", typeof(string)); - - } } /// /// A Revit Level @@ -133,7 +118,9 @@ private void InitLevel(double elevation, string name) var traceData = new LevelTraceData(this, name); TransactionManager.Instance.TransactionTaskDone(); - ElementBinder.SetRawDataForTrace(traceData); + var serializedTraceData = JsonConvert.SerializeObject(traceData); + + ElementBinder.SetRawDataForTrace(serializedTraceData); } @@ -194,7 +181,8 @@ private void InternalSetName(string oldname,string name) TransactionManager.Instance.EnsureInTransaction(Document); this.InternalLevel.Name = name; var updatedTraceData =new LevelTraceData(this, originalInputName); - ElementBinder.SetRawDataForTrace(updatedTraceData); + var serializedTraceData = JsonConvert.SerializeObject(updatedTraceData); + ElementBinder.SetRawDataForTrace(serializedTraceData); TransactionManager.Instance.TransactionTaskDone(); } diff --git a/src/Libraries/RevitServices/Persistence/ElementBinder.cs b/src/Libraries/RevitServices/Persistence/ElementBinder.cs index 7ae4cbc746..85ceebb1c7 100644 --- a/src/Libraries/RevitServices/Persistence/ElementBinder.cs +++ b/src/Libraries/RevitServices/Persistence/ElementBinder.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; using Autodesk.Revit.DB; using Dynamo.Engine; using Dynamo.Graph.Nodes; @@ -11,42 +10,18 @@ using ProtoCore; using RevitServices.Elements; using Microsoft.CSharp; +using Newtonsoft.Json; namespace RevitServices.Persistence { /// /// Holds a representation of a Revit ID that supports serialisation /// - [Serializable] - public class SerializableId : ISerializable + public class SerializableId { public String StringID { get; set; } public long IntID { get; set; } - public virtual void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("stringID", StringID, typeof(string)); - info.AddValue("intID", IntID, typeof(long)); - } - - public SerializableId() - { - StringID = ""; - IntID = long.MinValue; - - } - - /// - /// Ctor used by the serialisation engine - /// - /// - /// - public SerializableId(SerializationInfo info, StreamingContext context) - { - StringID = (string) info.GetValue("stringID", typeof (string)); - IntID = (long)info.GetValue("intID", typeof(long)); - } - public override bool Equals(object other) { var sID = other as SerializableId; @@ -67,27 +42,11 @@ public override int GetHashCode() //@TODO: This could be used to hold all the serializableIds - [Serializable] - public class MultipleSerializableId : ISerializable + public class MultipleSerializableId { public List StringIDs { get; set; } public List IntIDs { get; set; } - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - Validity.Assert(StringIDs.Count == IntIDs.Count); - - int numberOfElements = StringIDs.Count; - - info.AddValue("numberOfElements", numberOfElements); - - for (int i = 0; i < numberOfElements; i++) - { - info.AddValue("stringID-" + i, StringIDs[i], typeof(string)); - info.AddValue("intID-" + i, IntIDs[i], typeof(long)); - } - } - public MultipleSerializableId() { InitializeDataMembers(); @@ -104,26 +63,10 @@ public MultipleSerializableId(IEnumerable elements) } } - /// - /// Ctor used by the serialisation engine - /// - /// - /// - public MultipleSerializableId(SerializationInfo info, StreamingContext context) + public MultipleSerializableId(List stringIDs, List intIDs) { - InitializeDataMembers(); - - int numberOfElements = info.GetInt32("numberOfElements"); - - for (int i = 0; i < numberOfElements; i++) - { - string stringID = (string)info.GetValue("stringID-" + i, typeof(string)); - long intID = (long)info.GetValue("intID-" + i, typeof(long)); - - StringIDs.Add(stringID); - IntIDs.Add(intID); - } - + StringIDs = stringIDs; + IntIDs = intIDs; } private void InitializeDataMembers() @@ -204,9 +147,21 @@ public class ElementBinder public static ElementId GetElementIdFromTrace(Document document) { //Get the element ID that was cached in the callsite - ISerializable traceData = TraceUtils.GetTraceData(REVIT_TRACE_ID); + string traceString = TraceUtils.GetTraceData(REVIT_TRACE_ID); + + if (String.IsNullOrEmpty(traceString)) + return null; + + SerializableId id = null; + try + { + id = JsonConvert.DeserializeObject(traceString); + } + catch + { + //do nothing + } - SerializableId id = traceData as SerializableId; if (id == null) return null; //There was no usable data in the trace cache @@ -222,11 +177,23 @@ public static ElementId GetElementIdFromTrace(Document document) public static ElementUUID GetElementUUIDFromTrace(Document document) { //Get the element ID that was cached in the callsite - ISerializable traceData = TraceUtils.GetTraceData(REVIT_TRACE_ID); + string traceString = TraceUtils.GetTraceData(REVIT_TRACE_ID); + + if(String.IsNullOrEmpty(traceString)) + return null; - SerializableId id = traceData as SerializableId; + SerializableId id = null; + try + { + id = JsonConvert.DeserializeObject(traceString); + } + catch + { + //do nothing + } + if (id == null) - return null; //There was no usable data in the trace cache + return null; //There was no usable data in the trace cache var traceDataUuid = id.StringID; return new ElementUUID(traceDataUuid); @@ -240,9 +207,20 @@ public static ElementUUID GetElementUUIDFromTrace(Document document) public static List GetElementUUIDsFromTrace(Document document) { //Get the element ID that was cached in the callsite - ISerializable traceData = TraceUtils.GetTraceData(REVIT_TRACE_ID); + string traceString = TraceUtils.GetTraceData(REVIT_TRACE_ID); + + if (String.IsNullOrEmpty(traceString)) + return null; - var multi = traceData as MultipleSerializableId; + MultipleSerializableId multi = null; + try + { + multi = JsonConvert.DeserializeObject(traceString); + } + catch + { + //do nothing + } if (multi != null) { @@ -253,7 +231,16 @@ public static List GetElementUUIDsFromTrace(Document document) return uuids; } - var single = traceData as SerializableId; + SerializableId single = null; + try + { + single = JsonConvert.DeserializeObject(traceString); + } + catch + { + //do nothing + } + if (single != null) { var traceDataUuid = single.StringID; @@ -304,7 +291,10 @@ public static void SetElementsForTrace(IEnumerable elements) if (!IsEnabled) return; MultipleSerializableId ids = new MultipleSerializableId(elements); - TraceUtils.SetTraceData(REVIT_TRACE_ID, ids); + + var serializedTraceData = JsonConvert.SerializeObject(ids); + + TraceUtils.SetTraceData(REVIT_TRACE_ID, serializedTraceData); } @@ -325,9 +315,9 @@ public static void SetElementForTrace(ElementId elementId, ElementUUID elementUU // if we're mutating the current Element id, that means we need to // clean up the old object + var serializedTraceData = JsonConvert.SerializeObject(id); // Set the element ID cached in the callsite - TraceUtils.SetTraceData(REVIT_TRACE_ID, id); - + TraceUtils.SetTraceData(REVIT_TRACE_ID, serializedTraceData); } /// @@ -411,7 +401,7 @@ public static void CleanupAndSetElementForTrace(Document document, Element newEl /// the interpretation of the data /// /// - public static void SetRawDataForTrace(ISerializable data) + public static void SetRawDataForTrace(string data) { if (!IsEnabled) return; TraceUtils.SetTraceData(REVIT_TRACE_ID, data); @@ -421,7 +411,7 @@ public static void SetRawDataForTrace(ISerializable data) /// Raw method for getting data from the trace cache, the user is responsible for handling the interpretation /// of the data /// - public static ISerializable GetRawDataFromTrace() + public static string GetRawDataFromTrace() { return TraceUtils.GetTraceData(REVIT_TRACE_ID); } @@ -435,16 +425,25 @@ public static Tuple GetElementAndTraceData(Documen where TElement : Autodesk.Revit.DB.Element where TId: SerializableId { - var id = ElementBinder.GetRawDataFromTrace(); - if (id == null) + var traceString = ElementBinder.GetRawDataFromTrace(); + if (String.IsNullOrEmpty(traceString)) return null; - var traceData = id as TId; - if (traceData == null) + TId tid = null; + try + { + tid = JsonConvert.DeserializeObject(traceString); + } + catch + { + //do nothing + } + + if (tid == null) return null; - var elementId = traceData.IntID; - var uuid = traceData.StringID; + var elementId = tid.IntID; + var uuid = tid.StringID; var element = default(TElement); @@ -452,7 +451,7 @@ public static Tuple GetElementAndTraceData(Documen if (!document.TryGetElement(uuid,out element)) return null; - return new Tuple(element, traceData); + return new Tuple(element, tid); } /// /// This function gets the nodes which are binding with the elements which have the @@ -495,11 +494,22 @@ public static IEnumerable GetNodesFromElementIds(IEnumerable traceData = srtd.RecursiveGetNestedData(); + List traceData = srtd.RecursiveGetNestedData(); - foreach (ISerializable thingy in traceData) + foreach (string thingy in traceData) { - SerializableId sid = thingy as SerializableId; + if (String.IsNullOrEmpty(thingy)) + continue; + + SerializableId sid = null; + try + { + sid = JsonConvert.DeserializeObject(thingy); + } + catch + { + //do nothing + } if (sid != null) { @@ -565,11 +575,22 @@ public static void SetElementFreezeState(WorkspaceModel workspace, NodeModel nod { foreach (CallSite.SingleRunTraceData srtd in cs.TraceData) { - List traceData = srtd.RecursiveGetNestedData(); + List traceData = srtd.RecursiveGetNestedData(); - foreach (ISerializable thingy in traceData) + foreach (string thingy in traceData) { - SerializableId sid = thingy as SerializableId; + if (String.IsNullOrEmpty(thingy)) + continue; + + SerializableId sid = null; + try + { + sid = JsonConvert.DeserializeObject(thingy); + } + catch + { + //do nothing + } if (sid != null) { @@ -577,9 +598,19 @@ public static void SetElementFreezeState(WorkspaceModel workspace, NodeModel nod } - else if (thingy is MultipleSerializableId) + MultipleSerializableId msid = null; + try + { + msid = JsonConvert.DeserializeObject(thingy); + } + catch + { + //do nothing + } + + if (msid != null) { - (thingy as MultipleSerializableId).IntIDs.ForEach(x => setEachElementFreezeState(node.IsFrozen, x)); + msid.IntIDs.ForEach(x => setEachElementFreezeState(node.IsFrozen, x)); } } } From fe5175fa3769bf7ccbc550cecfc9fa181e1b2951 Mon Sep 17 00:00:00 2001 From: Craig Long Date: Sun, 19 Nov 2023 16:42:44 -0500 Subject: [PATCH 2/2] Update missing constructors --- src/Libraries/RevitNodes/Elements/DirectShape.cs | 9 +++++++++ src/Libraries/RevitNodes/Elements/Level.cs | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/src/Libraries/RevitNodes/Elements/DirectShape.cs b/src/Libraries/RevitNodes/Elements/DirectShape.cs index 3b8d2bd6b9..b0c159019b 100644 --- a/src/Libraries/RevitNodes/Elements/DirectShape.cs +++ b/src/Libraries/RevitNodes/Elements/DirectShape.cs @@ -23,6 +23,15 @@ public class DirectShapeState : SerializableId public string syncId { get; set; } public long materialId { get; set; } + [JsonConstructor] + public DirectShapeState(int intID, string stringID, string syncId, long materialId) + { + IntID = intID; + StringID = stringID; + this.syncId = syncId; + this.materialId = materialId; + } + public DirectShapeState(DirectShape ds, string syncId, ElementId materialId) : base() { diff --git a/src/Libraries/RevitNodes/Elements/Level.cs b/src/Libraries/RevitNodes/Elements/Level.cs index 94d93688a9..be5463ccb9 100644 --- a/src/Libraries/RevitNodes/Elements/Level.cs +++ b/src/Libraries/RevitNodes/Elements/Level.cs @@ -21,6 +21,14 @@ public class LevelTraceData : SerializableId { public string InputName { get; set; } + [JsonConstructor] + public LevelTraceData(int intID, string stringID, string inputName) + { + IntID = intID; + StringID = stringID; + InputName = inputName; + } + public LevelTraceData(Level lev, string inputName) : base() {