Skip to content

Commit c611dbb

Browse files
committed
refactor and add unit test for AssetProperties_Item
1 parent 013981e commit c611dbb

19 files changed

+172
-58
lines changed

sources/RevitDBExplorer/Domain/DataModel/Accessors/IAccessorWithReadAndSnoop.cs renamed to sources/RevitDBExplorer/Domain/DataModel/Accessors/IAccessorForDefaultPresenter.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
using System.Collections.Generic;
22
using RevitDBExplorer.Domain.DataModel.ValueContainers.Base;
3+
using RevitExplorer.Visualizations.DrawingVisuals;
34

45
// (c) Revit Database Explorer https://github.com/NeVeSpl/RevitDBExplorer/blob/main/license.md
56

67
namespace RevitDBExplorer.Domain.DataModel.Accessors
78
{
8-
internal interface IAccessorWithReadAndSnoop : IAccessor
9+
internal interface IAccessorForDefaultPresenter : IAccessor
910
{
1011
ReadResult Read(SnoopableContext context, object @object);
1112
IEnumerable<SnoopableObject> Snoop(SnoopableContext context, object @object, IValueContainer state);
13+
IEnumerable<DrawingVisual> GetVisualization(SnoopableContext context, object @object, IValueContainer state);
1214
}
1315
}

sources/RevitDBExplorer/Domain/DataModel/Accessors/ReadResult.cs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,41 @@
1-
using RevitDBExplorer.Domain.DataModel.ValueContainers.Base;
1+
using System.Diagnostics.CodeAnalysis;
2+
using RevitDBExplorer.Domain.DataModel.ValueContainers.Base;
23

34
// (c) Revit Database Explorer https://github.com/NeVeSpl/RevitDBExplorer/blob/main/license.md
45

56
namespace RevitDBExplorer.Domain.DataModel.Accessors
67
{
78
internal readonly ref struct ReadResult
89
{
9-
public string Label { get; init; }
10+
public required string Label { get; init; }
1011
public string AccessorName { get; init; }
11-
public bool CanBeSnooped { get; init; }
12+
public required bool CanBeSnooped { get; init; } = false;
13+
public bool CanBeVisualized { get; init; } = false;
1214
public IValueContainer State { get; init; }
1315

1416

15-
public ReadResult(string value, string accessorName, bool canBeSnooped, IValueContainer state = null)
17+
public ReadResult()
1618
{
17-
Label = value;
19+
20+
}
21+
22+
23+
[SetsRequiredMembers]
24+
public ReadResult(string label, string accessorName, bool canBeSnooped, IValueContainer state = null)
25+
{
26+
Label = label;
27+
AccessorName = accessorName;
28+
CanBeSnooped = canBeSnooped;
29+
State = state;
30+
}
31+
32+
[SetsRequiredMembers]
33+
public ReadResult(string label, string accessorName, bool canBeSnooped = false, bool canBeVisualized = false, IValueContainer state = null)
34+
{
35+
Label = label;
1836
AccessorName = accessorName;
1937
CanBeSnooped = canBeSnooped;
38+
CanBeVisualized = canBeVisualized;
2039
State = state;
2140
}
2241
}

sources/RevitDBExplorer/Domain/DataModel/MemberAccessors/AssetProperties/AssetProperties_Item.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
using System.Collections.Generic;
22
using System.Linq.Expressions;
3-
using Autodesk.Revit.DB;
43
using Autodesk.Revit.DB.Visual;
4+
using RevitDBExplorer.Domain.DataModel.Accessors;
5+
using RevitDBExplorer.Domain.DataModel.ValueContainers.Base;
56

67
// (c) Revit Database Explorer https://github.com/NeVeSpl/RevitDBExplorer/blob/main/license.md
78

89
namespace RevitDBExplorer.Domain.DataModel.MemberAccessors
910
{
10-
internal class AssetProperties_Item : MemberAccessorByType<AssetProperties>, ICanCreateMemberAccessor
11+
internal class AssetProperties_Item : MemberAccessorTypedWithDefaultPresenter<AssetProperties>, ICanCreateMemberAccessor
1112
{
12-
IEnumerable<LambdaExpression> ICanCreateMemberAccessor.GetHandledMembers() { yield return (AssetProperties x) => x[0]; }
13+
IEnumerable<LambdaExpression> ICanCreateMemberAccessor.GetHandledMembers() { yield return (AssetProperties x) => x[0]; }
1314

1415

15-
protected override bool CanBeSnoooped(Document document, AssetProperties assetProperties) => assetProperties.Size > 0;
16-
protected override string GetLabel(Document document, AssetProperties assetProperties) => $"[{nameof(AssetProperty)} : {assetProperties.Size}]";
17-
protected override IEnumerable<SnoopableObject> Snooop(Document document, AssetProperties assetProperties)
16+
public override ReadResult Read(SnoopableContext context, AssetProperties assetProperties) => new()
17+
{
18+
Label = Labeler.GetLabelForCollection(nameof(AssetProperty), assetProperties.Size),
19+
CanBeSnooped = assetProperties.Size > 0
20+
};
21+
22+
public override IEnumerable<SnoopableObject> Snoop(SnoopableContext context, AssetProperties assetProperties, IValueContainer state)
1823
{
1924
for (int i = 0; i < assetProperties.Size; i++)
2025
{
21-
yield return new SnoopableObject(document, assetProperties[i]);
26+
yield return new SnoopableObject(context.Document, assetProperties[i]);
2227
}
2328
}
2429
}

sources/RevitDBExplorer/Domain/DataModel/MemberAccessors/MemberAccessorByFunc.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace RevitDBExplorer.Domain.DataModel.MemberAccessors
1010
{
11-
internal class MemberAccessorByFunc<TSnoopedObjectType, TReturnType> : MemberAccessorTypedWithReadAndSnoop<TSnoopedObjectType>
11+
internal class MemberAccessorByFunc<TSnoopedObjectType, TReturnType> : MemberAccessorTypedWithDefaultPresenter<TSnoopedObjectType>
1212
{
1313
private readonly Func<Document, TSnoopedObjectType, TReturnType> get;
1414
private readonly Func<Document, TSnoopedObjectType, IEnumerable<SnoopableObject>> snoop;
@@ -25,7 +25,7 @@ public override ReadResult Read(SnoopableContext context, TSnoopedObjectType @ob
2525
var value = new ValueContainer<TReturnType>();
2626
var result = get(context.Document, @object);
2727
value.SetValueTyped(context, result);
28-
return new ReadResult(value.ValueAsString, "[ByFunc] " + value.TypeHandlerName, value.CanBeSnooped, value);
28+
return new ReadResult(value.ValueAsString, "[ByFunc] " + value.TypeHandlerName, value.CanBeSnooped, value.CanBeVisualized, value);
2929
}
3030
public override IEnumerable<SnoopableObject> Snoop(SnoopableContext context, TSnoopedObjectType @object, IValueContainer state)
3131
{

sources/RevitDBExplorer/Domain/DataModel/MemberAccessors/MemberAccessorByIteration.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
namespace RevitDBExplorer.Domain.DataModel.MemberAccessors
1212
{
13-
internal sealed class MemberAccessorByIteration<TSnoopedObjectType, TReturnType> : MemberAccessorTypedWithReadAndSnoop<TSnoopedObjectType>
13+
internal sealed class MemberAccessorByIteration<TSnoopedObjectType, TReturnType> : MemberAccessorTypedWithDefaultPresenter<TSnoopedObjectType>
1414
{
1515
private readonly string getMethodReturnTypeName;
1616
private readonly ParameterInfo getMethodParameter;
@@ -30,7 +30,7 @@ public MemberAccessorByIteration(MethodInfo getMethod)
3030
public override ReadResult Read(SnoopableContext context, TSnoopedObjectType @object)
3131
{
3232
var count = CountValues(context, getMethodParameter.ParameterType);
33-
return new ReadResult(Labeler.GetLabelForCollection(getMethodReturnTypeName, count), "[ByIteration]", true);
33+
return new ReadResult(Labeler.GetLabelForCollection(getMethodReturnTypeName, count), "[ByIteration]", true, false);
3434
}
3535
public override IEnumerable<SnoopableObject> Snoop(SnoopableContext context, TSnoopedObjectType @object, IValueContainer state)
3636
{

sources/RevitDBExplorer/Domain/DataModel/MemberAccessors/MemberAccessorByRef.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
namespace RevitDBExplorer.Domain.DataModel.MemberAccessors
1212
{
13-
internal sealed class MemberAccessorByRef : MemberAccessorTypedWithReadAndSnoop<object>, IAccessorWithCodeGeneration
13+
internal sealed class MemberAccessorByRef : MemberAccessorTypedWithDefaultPresenter<object>, IAccessorWithCodeGeneration
1414
{
1515
private readonly MethodInfo getMethod;
1616

@@ -28,12 +28,9 @@ public override ReadResult Read(SnoopableContext context, object @object)
2828
var resolvedArgs = ResolveArguments(paramsDef, context.Document, @object);
2929
var result = getMethod.Invoke(@object, resolvedArgs);
3030
value.SetValue(context, result);
31-
return new ReadResult(value.ValueAsString, "[ByRef] " + value.TypeHandlerName, value.CanBeSnooped, value);
32-
}
33-
public override IEnumerable<SnoopableObject> Snoop(SnoopableContext context, object @object, IValueContainer state)
34-
{
35-
return state.Snoop();
31+
return new ReadResult(value.ValueAsString, "[ByRef] " + value.TypeHandlerName, value.CanBeSnooped, value.CanBeVisualized, value);
3632
}
33+
3734

3835
public static Type[] HandledParameterTypes = new[] { typeof(Document), typeof(Options), typeof(View), typeof(SpatialElementBoundaryOptions) };
3936

sources/RevitDBExplorer/Domain/DataModel/MemberAccessors/MemberAccessorByRefCompiled.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace RevitDBExplorer.Domain.DataModel.MemberAccessors
1111
{
12-
internal sealed class MemberAccessorByRefCompiled<TSnoopedObjectType, TReturnType> : MemberAccessorTypedWithReadAndSnoop<TSnoopedObjectType>, IAccessorWithCodeGeneration
12+
internal sealed class MemberAccessorByRefCompiled<TSnoopedObjectType, TReturnType> : MemberAccessorTypedWithDefaultPresenter<TSnoopedObjectType>, IAccessorWithCodeGeneration
1313
{
1414
private readonly MethodInfo getMethod;
1515
private readonly Func<TSnoopedObjectType, TReturnType> func;
@@ -25,13 +25,8 @@ public override ReadResult Read(SnoopableContext context, TSnoopedObjectType typ
2525
var value = new ValueContainer<TReturnType>();
2626
var result = func(typedObject);
2727
value.SetValueTyped(context, result);
28-
return new ReadResult(value.ValueAsString, "[ByRefComp] " + value.TypeHandlerName, value.CanBeSnooped, value);
29-
}
30-
31-
public override IEnumerable<SnoopableObject> Snoop(SnoopableContext context, TSnoopedObjectType typedObject, IValueContainer state)
32-
{
33-
return state.Snoop();
34-
}
28+
return new ReadResult(value.ValueAsString, "[ByRefComp] " + value.TypeHandlerName, value.CanBeSnooped, value.CanBeVisualized, value);
29+
}
3530

3631

3732
public string GenerateInvocationForScript(TemplateInputsKind inputsKind)

sources/RevitDBExplorer/Domain/DataModel/MemberAccessors/MemberAccessorByType.cs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@
99

1010
namespace RevitDBExplorer.Domain.DataModel.MemberAccessors
1111
{
12-
internal abstract class MemberAccessorByType<TSnoopedObjectType> : MemberAccessorTypedWithReadAndSnoop<TSnoopedObjectType> where TSnoopedObjectType : class
12+
internal abstract class MemberAccessorByType<TSnoopedObjectType> : MemberAccessorTypedWithDefaultPresenter<TSnoopedObjectType> where TSnoopedObjectType : class
1313
{
1414
public sealed override ReadResult Read(SnoopableContext context, TSnoopedObjectType @object)
1515
{
1616
string label = GetLabel(context.Document, @object);
1717
bool canBeSnooped = CanBeSnoooped(context.Document, @object);
18+
bool canBeVisualized = false;
1819

19-
return new ReadResult(label, "[ByType] " + GetType().GetCSharpName(), canBeSnooped);
20+
return new ReadResult(label, "[ByType] " + GetType().GetCSharpName(), canBeSnooped, canBeVisualized);
2021
}
2122
protected abstract bool CanBeSnoooped(Document document, TSnoopedObjectType value);
2223
protected abstract string GetLabel(Document document, TSnoopedObjectType value);
@@ -27,4 +28,34 @@ public sealed override IEnumerable<SnoopableObject> Snoop(SnoopableContext conte
2728
}
2829
protected virtual IEnumerable<SnoopableObject> Snooop(Document document, TSnoopedObjectType value) => Enumerable.Empty<SnoopableObject>();
2930
}
31+
32+
33+
internal abstract class MemberAccessorByTypeLambda<TSnoopedObjectType> : MemberAccessorByType<TSnoopedObjectType> where TSnoopedObjectType : class
34+
{
35+
public Overrides Override { get; } = new Overrides();
36+
37+
protected override bool CanBeSnoooped(Document document, TSnoopedObjectType value)
38+
{
39+
ArgumentNullException.ThrowIfNull(Override.CanBeSnooped);
40+
return Override.CanBeSnooped(document, value);
41+
}
42+
protected override string GetLabel(Document document, TSnoopedObjectType value)
43+
{
44+
ArgumentNullException.ThrowIfNull(Override.GetLabel);
45+
return Override.GetLabel(document, value);
46+
}
47+
protected override IEnumerable<SnoopableObject> Snooop(Document document, TSnoopedObjectType value)
48+
{
49+
if (Override.Snoop == null) return null;
50+
return Override.Snoop(document, value);
51+
}
52+
53+
54+
public class Overrides
55+
{
56+
public Func<Document, TSnoopedObjectType, bool> CanBeSnooped { get; set; }
57+
public Func<Document, TSnoopedObjectType, string> GetLabel { get; set; }
58+
public Func<Document, TSnoopedObjectType, IEnumerable<SnoopableObject>> Snoop { get; set; }
59+
}
60+
}
3061
}

sources/RevitDBExplorer/Domain/DataModel/MemberAccessors/MemberAccessorFactory.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace RevitDBExplorer.Domain.DataModel.MemberAccessors
1111
{
1212
internal static class MemberAccessorFactory
1313
{
14-
private static readonly Dictionary<string, Func<IAccessor>> forTypeMembers = new();
14+
private static readonly Dictionary<string, Func<IAccessor>> memberAccessorOverrides = new();
1515

1616

1717
public static void Init()
@@ -26,7 +26,7 @@ static MemberAccessorFactory()
2626
foreach (var handledMember in accessor.GetHandledMembers())
2727
{
2828
var memberId = handledMember.GetUniqueId();
29-
forTypeMembers[memberId] = accessor.GetType().CompileFactoryMethod<IAccessor>();
29+
memberAccessorOverrides[memberId] = accessor.GetType().CompileFactoryMethod<IAccessor>();
3030
}
3131
}
3232
}
@@ -50,20 +50,20 @@ public static IAccessor CreateMemberAccessor(MethodInfo getMethod, MethodInfo se
5050

5151
private static IAccessor CreateMemberAccessor(MethodInfo getMethod)
5252
{
53+
if (memberAccessorOverrides.TryGetValue(getMethod.GetUniqueId(), out Func<IAccessor> factory))
54+
{
55+
return factory();
56+
}
57+
5358
if (getMethod.IsStatic)
5459
{
5560
return new MemberAccessorForStatic(getMethod);
5661
}
5762

58-
if (getMethod.ReturnType == typeof(void) && getMethod.Name != "GetOverridableHookParameters")
63+
if (getMethod.ReturnType == typeof(void))
5964
{
6065
return new MemberAccessorForNotExposed(getMethod);
61-
}
62-
63-
if (forTypeMembers.TryGetValue(getMethod.GetUniqueId(), out Func<IAccessor> factory))
64-
{
65-
return factory();
66-
}
66+
}
6767

6868
var @params = getMethod.GetParameters();
6969

sources/RevitDBExplorer/Domain/DataModel/MemberAccessors/MemberAccessorForConstValue.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace RevitDBExplorer.Domain.DataModel.MemberAccessors
99
{
10-
internal sealed class MemberAccessorForConstValue : MemberAccessorTypedWithReadAndSnoop<object>
10+
internal sealed class MemberAccessorForConstValue : MemberAccessorTypedWithDefaultPresenter<object>
1111
{
1212
private readonly IValueContainer value;
1313

0 commit comments

Comments
 (0)