using Speckle.Objects.Other; using Speckle.Sdk.Dependencies; using Speckle.Sdk.Models; using Speckle.Sdk.Models.Collections; using Speckle.Sdk.Models.GraphTraversal; using Speckle.Sdk.Models.Instances; using Speckle.Sdk.Models.Proxies; namespace Speckle.Connectors.Common.Operations.Receive; /// /// Unpacker root object for receive operation. /// public class RootObjectUnpacker { private readonly GraphTraversal _traverseFunction; public RootObjectUnpacker(GraphTraversal traverseFunction) { _traverseFunction = traverseFunction; } public RootObjectUnpackerResult Unpack(Base root) => new( GetObjectsToConvert(root), TryGetInstanceDefinitionProxies(root), TryGetGroupProxies(root), TryGetRenderMaterialProxies(root), TryGetColorProxies(root), TryGetLevelProxies(root) ); public IReadOnlyCollection GetObjectsToConvert(Base root) => _traverseFunction.Traverse(root).Where(obj => obj.Current is not Collection).Freeze(); public IReadOnlyCollection? TryGetColorProxies(Base root) => TryGetProxies(root, ProxyKeys.COLOR); public IReadOnlyCollection? TryGetRenderMaterialProxies(Base root) => TryGetProxies(root, ProxyKeys.RENDER_MATERIAL); public IReadOnlyCollection? TryGetInstanceDefinitionProxies(Base root) => TryGetProxies(root, ProxyKeys.INSTANCE_DEFINITION); public IReadOnlyCollection? TryGetGroupProxies(Base root) => TryGetProxies(root, ProxyKeys.GROUP); public IReadOnlyCollection? TryGetLevelProxies(Base root) => TryGetProxies(root, ProxyKeys.LEVEL); public ( IReadOnlyCollection atomicObjects, IReadOnlyCollection instanceComponents ) SplitAtomicObjectsAndInstances(IEnumerable objectsToSplit) { HashSet atomicObjects = new(); HashSet instanceComponents = new(); foreach (TraversalContext tc in objectsToSplit) { if (tc.Current is IInstanceComponent) { instanceComponents.Add(tc); } else { atomicObjects.Add(tc); } } return (atomicObjects.Freeze(), instanceComponents.Freeze()); } private IReadOnlyCollection? TryGetProxies(Base root, string key) => (root[key] as List)?.Cast().ToList(); }