Skip to content

Commit

Permalink
Comments
Browse files Browse the repository at this point in the history
  • Loading branch information
bjoernsteinhagen committed Dec 2, 2024
1 parent 71b3298 commit fce77fc
Show file tree
Hide file tree
Showing 19 changed files with 101 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,23 @@ public class CSiSharedSelectionBinding : ISelectionBinding
{
public string Name => "selectionBinding";
public IBrowserBridge Parent { get; }
private readonly ICSiApplicationService _csiApplicationService; // Update selection binding to centralized CSiSharedApplicationService instead of trying to maintain a reference to "sapModel"
private readonly ICSiApplicationService _csiApplicationService;

public CSiSharedSelectionBinding(IBrowserBridge parent, ICSiApplicationService csiApplicationService)
{
Parent = parent;
_csiApplicationService = csiApplicationService;
}

/// <summary>
/// Gets the selection and creates an encoded ID (objectType and objectName).
/// </summary>
/// <remarks>
/// Refer to ObjectIdentifier.cs for more info.
/// </remarks>
public SelectionInfo GetSelection()
{
// TODO: Handle better. Enums? ObjectType same in ETABS and SAP
// TODO: Since this is standard across CSi Suite - better stored in an enum?
var objectTypeMap = new Dictionary<int, string>
{
{ 1, "Point" },
Expand All @@ -46,7 +52,7 @@ public SelectionInfo GetSelection()
var typeName = objectTypeMap.TryGetValue(typeKey, out var name) ? name : $"Unknown ({typeKey})";

encodedIds.Add(ObjectIdentifier.Encode(typeKey, objectName[i]));
typeCounts[typeName] = (typeCounts.TryGetValue(typeName, out var count) ? count : 0) + 1; // NOTE: Cross-framework compatibility
typeCounts[typeName] = (typeCounts.TryGetValue(typeName, out var count) ? count : 0) + 1; // NOTE: Cross-framework compatibility (net 48 and net8)
}

var summary =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public sealed class CSiSharedSendBinding : ISendBinding
private readonly CancellationManager _cancellationManager;
private readonly IOperationProgressManager _operationProgressManager;
private readonly ILogger<CSiSharedSendBinding> _logger;
private readonly ICSiApplicationService _csiApplicationService; // Update selection binding to centralized CSiSharedApplicationService instead of trying to maintain a reference to "sapModel"
private readonly ICSiApplicationService _csiApplicationService; // Update selection binding to centralized CSiApplicationService instead of trying to maintain a reference to "sapModel"
private readonly ICSiConversionSettingsFactory _csiConversionSettingsFactory;
private readonly ISpeckleApplication _speckleApplication;
private readonly ISdkActivityFactory _activityFactory;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace Speckle.Connectors.CSiShared.HostApp;

/// <summary>
/// Create a centralized access point for ETABS and SAP APIs across the entire program.
/// </summary>
/// <remarks>
/// All API methods are based on the objectType and objectName, not the GUID.
/// CSi is already giving us the "sapModel" reference through the plugin interface. No need to attach to running instance.
/// Since objectType is a single int (1, 2 ... 7) we know first index will always be the objectType.
/// Prevent having to pass the "sapModel" around between classes and this ensures consistent access.
/// Name "sapModel" is misleading since it doesn't only apply to SAP2000, but this is the convention in the API, so we keep it.
/// </remarks>
public interface ICSiApplicationService
{
cSapModel SapModel { get; }
void Initialize(cSapModel sapModel, cPluginCallback pluginCallback);
}

public class CSiApplicationService : ICSiApplicationService
{
public cSapModel SapModel { get; private set; }
private cPluginCallback _pluginCallback;

public CSiApplicationService()
{
SapModel = null!;
}

public void Initialize(cSapModel sapModel, cPluginCallback pluginCallback)
{
SapModel = sapModel;
_pluginCallback = pluginCallback;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@

namespace Speckle.Connectors.CSiShared.HostApp;

public class CSiSharedDocumentModelStore : DocumentModelStore
public class CSiDocumentModelStore : DocumentModelStore
{
private readonly ISpeckleApplication _speckleApplication;
private readonly ILogger<CSiSharedDocumentModelStore> _logger;
private readonly ILogger<CSiDocumentModelStore> _logger;
private readonly ICSiApplicationService _csiApplicationService;
private string HostAppUserDataPath { get; set; }
private string DocumentStateFile { get; set; }
private string ModelPathHash { get; set; }

public CSiSharedDocumentModelStore(
public CSiDocumentModelStore(
IJsonSerializer jsonSerializerSettings,
ISpeckleApplication speckleApplication,
ILogger<CSiSharedDocumentModelStore> logger,
ILogger<CSiDocumentModelStore> logger,
ICSiApplicationService csiApplicationService
)
: base(jsonSerializerSettings)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@

namespace Speckle.Connectors.CSiShared.HostApp;

public sealed class CSiSharedIdleManager : AppIdleManager
public sealed class CSiIdleManager : AppIdleManager
{
private readonly IIdleCallManager _idleCallManager;

public CSiSharedIdleManager(IIdleCallManager idleCallManager)
public CSiIdleManager(IIdleCallManager idleCallManager)
: base(idleCallManager)
{
_idleCallManager = idleCallManager;
}

protected override void AddEvent()
{
// ETABS specific idle handling can be added here if needed
// TODO: CSi specific idle handling can be added here if needed
_idleCallManager.AppOnIdle(() => { });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@

namespace Speckle.Connectors.CSiShared.HostApp;

/// <summary>
/// We can use the CSiWrappers to create our collection structure.
/// </summary>
/// <remarks>
/// This class manages the collections. If the key (from the path) already exists, this collection is returned.
/// If it doesn't exist, a new collection is created and added to the rootObject.
/// </remarks>
public class CSiSendCollectionManager
{
private readonly IConverterSettingsStore<CSiConversionSettings> _converterSettings;
Expand All @@ -14,7 +21,7 @@ public CSiSendCollectionManager(IConverterSettingsStore<CSiConversionSettings> c
_converterSettings = converterSettings;
}

// TODO: Frames could be further classified under Columns, Braces and Beams. Same for shells: walls, floors
// TODO: Frames could be further classified under Columns, Braces and Beams. Same for Shells which could be classified into walls, floors
public Collection GetAndCreateObjectHostCollection(ICSiWrapper csiObject, Collection rootObject)
{
var path = csiObject.GetType().Name.Replace("Wrapper", ""); // CSiJointWrapper → CSiJoint, CSiFrameWrapper → CSiFrame etc.
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
namespace Speckle.Connectors.CSiShared;

[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
public abstract class CSiSharedPluginBase : cPluginContract, IDisposable
public abstract class CSiPluginBase : cPluginContract, IDisposable
{
private const string s_modality = "Non-Modal";
private SpeckleFormBase? _panel;
Expand Down Expand Up @@ -50,7 +50,7 @@ public void Dispose()
GC.SuppressFinalize(this);
}

~CSiSharedPluginBase()
~CSiPluginBase()
{
Dispose(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@ public static IServiceCollection AddCSi(this IServiceCollection services)
services.AddSingleton<ICSiApplicationService, CSiApplicationService>();

services.AddConnectorUtils();
services.AddDUI<CSiSharedDocumentModelStore>();
services.AddDUI<CSiDocumentModelStore>();
services.AddDUIView();

services.AddSingleton<DocumentModelStore, CSiSharedDocumentModelStore>();
services.AddSingleton<DocumentModelStore, CSiDocumentModelStore>();

services.AddSingleton<IBinding, TestBinding>();
services.AddSingleton<IBinding, ConfigBinding>();
services.AddSingleton<IBinding, AccountBinding>();

services.AddSingleton<IBinding>(sp => sp.GetRequiredService<IBasicConnectorBinding>());
services.AddSingleton<IBasicConnectorBinding, CSiSharedBasicConnectorBinding>();
services.AddSingleton<IAppIdleManager, CSiSharedIdleManager>();
services.AddSingleton<IAppIdleManager, CSiIdleManager>();

services.AddSingleton<IBinding, CSiSharedSelectionBinding>();
services.AddSingleton<IBinding, CSiSharedSendBinding>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
<Compile Include="$(MSBuildThisFileDirectory)Filters\CSiSharedSelectionFilter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CSiSendCollectionManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\CSiRootObjectBuilder.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\CSiSharedPluginBase.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\CSiPluginBase.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\SpeckleFormBase.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)GlobalUsing.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CSiSharedApplicationService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CSiSharedDocumentModelStore.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CSiSharedIdleManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CSiApplicationService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CSiDocumentModelStore.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CSiIdleManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ServiceRegistration.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utils\ObjectIdentifiers.cs" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
namespace Speckle.Connectors.CSiShared.Utils;

// NOTE: All API methods are based on the objectType and objectName, not the GUID
// We will obviously manage the GUIDs but for all method calls we need a concatenated version of the objectType and objectName
// Since objectType >= 1 and <= 7, we know first index will always be the objectType
// Remaining string represents objectName and since the user can add any string (provided it is unique), this is safer
// than using a delimiting character (which could clash with user string)
/// <summary>
/// ObjectIdentifier based on concatenating the objectType and objectName. CSi is annoying, we can't use GUIDs.
/// </summary>
/// <remarks>
/// All API methods are based on the objectType and objectName, not the GUID.
/// We will obviously manage the GUIDs but for all method calls we need a concatenated version of the objectType and objectName.
/// Since objectType is a single int (1, 2 ... 7) we know first index will always be the objectType.
/// This int gets used by the CSiWrapperFactory to create the CSiWrappers.
/// </remarks>
public static class ObjectIdentifier
{
public static string Encode(int objectType, string objectName)
{
if (objectType < 1 || objectType > 7)
if (objectType < 1 || objectType > 7) // Both ETABS and SAP2000 APIs have the same returns for objectType
{
throw new ArgumentException($"Invalid object type: {objectType}. Must be between 1 and 7.");
}
Expand All @@ -18,7 +22,7 @@ public static string Encode(int objectType, string objectName)

public static (int type, string name) Decode(string encodedId)
{
if (string.IsNullOrEmpty(encodedId) || encodedId.Length < 2)
if (string.IsNullOrEmpty(encodedId) || encodedId.Length < 2) // Superfluous. But rather safe than sorry
{
throw new ArgumentException($"Invalid encoded ID: {encodedId}");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace Speckle.Connectors.ETABS21;

[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
public class cPlugin : CSiSharedPluginBase
public class cPlugin : CSiPluginBase
{
protected override SpeckleFormBase CreateForm() => new SpeckleForm();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace Speckle.Connectors.ETABS22;

[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
public class cPlugin : CSiSharedPluginBase
public class cPlugin : CSiPluginBase
{
protected override SpeckleFormBase CreateForm() => new SpeckleForm();
}
1 change: 1 addition & 0 deletions Converters/CSi/Speckle.Converters.CSiShared/CSiObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Speckle.Converters.CSiShared;

// NOTE: These are just temporarily here. Should be in SDK
[SpeckleType("Converters.CSiShared.CSiObject")]
public class CSiObject : Base, ICSiObject
{
Expand Down
15 changes: 15 additions & 0 deletions Converters/CSi/Speckle.Converters.CSiShared/CSiWrappers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ public interface ICSiWrapper
int ObjectType { get; }
}

/// <summary>
/// Based on GetSelected() returns of objectType and objectName, we need to create a CSiWrapper object.
/// </summary>
/// <remarks>
/// Creating a class that can be used to pass a type to the converter.
/// Since the API only provides a framework for us to query the model, we don't get instances.
/// The types are the same for both SAP 2000 and ETABS.
/// </remarks>
public abstract class CSiWrapperBase : ICSiWrapper
{
public required string Name { get; set; }
Expand Down Expand Up @@ -47,6 +55,13 @@ public class CSiLinkWrapper : CSiWrapperBase
public override int ObjectType => 7;
}

/// <summary>
/// ObjectType specific wrappers created during bindings.
/// </summary>
/// <remarks>
/// Switch statements based off of the objectType int return.
/// Used in the connectors and allows converters to be resolved effectively.
/// </remarks>
public static class CSiWrapperFactory
{
public static ICSiWrapper Create(int objectType, string name) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ ITypedConverter<CSiJointWrapper, Point> pointConverter
_pointConverter = pointConverter;
}

public Line Convert(CSiFrameWrapper target) // NOTE: THIS IS TEMPORARY
public Line Convert(CSiFrameWrapper target) // NOTE: THIS IS TEMPORARY POC
{
// frame points
string startPoint = "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Speckle.Converters.CSiShared.ToSpeckle.Raw;

// NOTE: This is HORRIBLE but serves just as a poc!
public class JointToSpeckleConverter : ITypedConverter<CSiJointWrapper, Point>
{
private readonly IConverterSettingsStore<CSiConversionSettings> _settingStore;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Speckle.Converters.CSiShared.ToSpeckle.Raw;

// NOTE: This is HORRIBLE but serves just as a poc! We need point caching and weak referencing to joint objects
public class ShellToSpeckleConverter : ITypedConverter<CSiShellWrapper, Mesh>
{
private readonly IConverterSettingsStore<CSiConversionSettings> _settingsStore;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public Base Convert(object target)
var result = new CSiObject
{
name = csiWrapper.Name,
type = csiWrapper.GetType().ToString().Split('.').Last().Replace("Wrapper", ""),
type = csiWrapper.GetType().ToString().Split('.').Last().Replace("Wrapper", ""), // CSiJointWrapper → CSiJoint, CSiFrameWrapper → CSiFrame etc.
units = _settingsStore.Current.SpeckleUnits,
// TODO: properties
displayValue = _displayValueExtractor.GetDisplayValue(csiWrapper).ToList()
Expand Down

0 comments on commit fce77fc

Please sign in to comment.