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