Skip to content

Commit

Permalink
Add Value loader and add support for C++ std::chrono::duration
Browse files Browse the repository at this point in the history
  • Loading branch information
awulkiew committed Nov 4, 2023
1 parent 251e6d5 commit 48fba16
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 22 deletions.
2 changes: 1 addition & 1 deletion solution/GraphicalDebugging/Debugger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public bool TryLoadDouble(string name, out double result)
{
result = 0.0;
string castedName = !IsLanguageBasic
? "(double)" + name
? "(double)(" + name + ")"
: "CType(" + name + ", Double)";
var expr = debugger.GetExpression(castedName);
return expr.IsValidValue
Expand Down
134 changes: 113 additions & 21 deletions solution/GraphicalDebugging/ExpressionLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;

namespace GraphicalDebugging
Expand All @@ -35,7 +36,7 @@ public enum Kind
Container = 0, MultiPoint, TurnsContainer, ValuesContainer, GeometriesContainer,
Point, Segment, Box, NSphere, Ray, Line, Linestring, Ring, Polygon,
MultiLinestring, MultiPolygon, MultiGeometry, Turn, OtherGeometry,
Variant, Image
Variant, Image, Value
};

public delegate void BreakModeEnteredEventHandler();
Expand Down Expand Up @@ -111,6 +112,8 @@ private ExpressionLoader(DTE2 dte)
loadersCpp.Add(new StdPairPoint.LoaderCreator());
loadersCpp.Add(new StdComplexPoint.LoaderCreator());

loadersCpp.Add(new StdChronoDuration.LoaderCreator());

loadersCpp.Add(new BVariant.LoaderCreator());

loadersCpp.Add(new StdArray.LoaderCreator());
Expand Down Expand Up @@ -231,7 +234,7 @@ public bool Check(Kind kind)
private readonly Kind mKind;
}

public class NonValueKindConstraint : IKindConstraint
public class NonValueContainerKindConstraint : IKindConstraint
{
public bool Check(Kind kind)
{
Expand All @@ -242,7 +245,11 @@ public bool Check(Kind kind)

public class DrawableKindConstraint : IKindConstraint
{
public bool Check(Kind kind) { return kind != Kind.Container; }
public bool Check(Kind kind)
{
return kind != Kind.Container
&& kind != Kind.Value;
}
}

// IMPORTANT: GeometriesContainer cannot be a Geometry,
Expand All @@ -254,7 +261,8 @@ public bool Check(Kind kind)
return kind != Kind.Container
&& kind != Kind.ValuesContainer
&& kind != Kind.GeometriesContainer
&& kind != Kind.Image;
&& kind != Kind.Image
&& kind != Kind.Value;
}
}

Expand All @@ -264,7 +272,8 @@ public bool Check(Kind kind)
{
return kind != Kind.Container
&& kind != Kind.ValuesContainer
&& kind != Kind.Image;
&& kind != Kind.Image
&& kind != Kind.Value;
}
}

Expand All @@ -284,7 +293,7 @@ public bool Check(Kind kind)
public static KindConstraint OnlyValuesContainers { get; } = new KindConstraint(Kind.ValuesContainer);
public static KindConstraint OnlyMultiPoints { get; } = new KindConstraint(Kind.MultiPoint);
public static IndexableKindConstraint OnlyIndexables { get; } = new IndexableKindConstraint();
public static NonValueKindConstraint OnlyNonValues { get; } = new NonValueKindConstraint();
public static NonValueContainerKindConstraint OnlyNonValueContainers { get; } = new NonValueContainerKindConstraint();

/// <summary>
/// Loads debugged variable into ExpressionDrawer.IDrawable and additional
Expand Down Expand Up @@ -3180,6 +3189,70 @@ public override ExpressionDrawer.IDrawable Load(MemoryReader mreader, Debugger d
readonly string pointType;
}

// TODO: Add abstract class and derive from it here
// TODO: Add user-defined Calue in ExpressionLoader_UserDefined
class Value : Loader
{
public Value(string memberName, string memberType)
{
this.memberName = memberName;
this.memberType = memberType;
}

public double Load(MemoryReader mreader, Debugger debugger, string name, string type)
{
// TODO: what if the actual value is NaN?
return debugger.TryLoadDouble(name + "." + memberName, out double result)
? result
: double.NaN;
}

public MemoryReader.Converter<double> GetMemoryConverter(MemoryReader mreader,
Debugger debugger, // TODO - remove
string name,
string type)
{
string member = name + "." + memberName;
if (!debugger.GetAddressOffset(name, member, out long memberOffset)
|| !debugger.GetTypeSizeof(member, out int memberSize))
return null;
MemoryReader.ValueConverter<double> memberConverter = mreader.GetNumericConverter(memberType, memberSize);
return memberConverter != null
&& debugger.GetTypeSizeof(type, out int sizeOfValue)
&& !Debugger.IsInvalidOffset(sizeOfValue, memberOffset)
? new MemoryReader.StructConverter<double>(
sizeOfValue,
new MemoryReader.Member<double>(memberConverter, (int)memberOffset))
: null;
}

private readonly string memberName;
private readonly string memberType;
}

class StdChronoDuration : Value
{
public class LoaderCreator : ExpressionLoader.ILoaderCreator
{
public bool IsUserDefined() { return false; }
public Kind Kind() { return ExpressionLoader.Kind.Value; }
public Loader Create(Loaders loaders, Debugger debugger, string name, string type, string id)
{
if (id != "std::chrono::duration")
return null;

List<string> tparams = Util.Tparams(type);
if (tparams.Count < 1)
return null;

return new StdChronoDuration("_MyRep", tparams[0]);
}
}

private StdChronoDuration(string memberName, string memberType) : base(memberName, memberType)
{}
}

class ValuesContainer : LoaderR<ExpressionDrawer.ValuesContainer>
{
public class LoaderCreator : ExpressionLoader.ILoaderCreator
Expand All @@ -3201,17 +3274,19 @@ public Loader Create(Loaders loaders, Debugger debugger, string name, string typ
containerLoader.ElementInfo(name, type, out string elName, out string elType);

// WARNING: Potentially recursive call, avoid searching for ValuesContainers
Loader l = loaders.FindByType(OnlyNonValues, elName, elType);
Loader l = loaders.FindByType(OnlyNonValueContainers, elName, elType);

return l == null // this is not non-value
? new ValuesContainer(containerLoader)
return l == null ? new ValuesContainer(containerLoader, null, elType)
: l is Value ? new ValuesContainer(containerLoader, l as Value, elType)
: null;
}
}

private ValuesContainer(ContainerLoader containerLoader)
private ValuesContainer(ContainerLoader containerLoader, Value valueLoader, string valueType)
{
this.containerLoader = containerLoader;
this.valueLoader = valueLoader;
this.valueType = valueType;
}

public override Geometry.Traits GetTraits(MemoryReader mreader, Debugger debugger,
Expand All @@ -3238,34 +3313,38 @@ public List<double> LoadValues(MemoryReader mreader, Debugger debugger,
List<double> result = null;

if (mreader != null)
LoadMemory(mreader, debugger, name, type, containerLoader, out result, callback);
LoadMemory(mreader, debugger, name, type, out result, callback);

if (result == null)
LoadParsed(debugger, name, containerLoader, out result, callback);
LoadParsed(mreader, debugger, name, type, out result, callback);

return result;
}

private void LoadMemory(MemoryReader mreader, Debugger debugger,
string name, string type,
ContainerLoader loader,
out List<double> result,
LoadCallback callback)
{
result = null;

loader.ElementInfo(name, type, out string elemName, out string elemType);
containerLoader.ElementInfo(name, type, out string elemName, out string elemType);

if (!debugger.GetTypeSizeof(elemType, out int valSize))
return;

MemoryReader.ValueConverter<double>
MemoryReader.Converter<double> valueConverter = null;

if (valueLoader != null)
valueConverter = valueLoader.GetMemoryConverter(mreader, debugger, elemName, elemType);
else
valueConverter = mreader.GetNumericConverter(elemType, valSize);

if (valueConverter == null)
return;

List<double> list = new List<double>();
bool ok = loader.ForEachMemoryBlock(mreader, debugger, name, type, 0, valueConverter,
bool ok = containerLoader.ForEachMemoryBlock(mreader, debugger, name, type, 0, valueConverter,
delegate (double[] values)
{
foreach (double v in values)
Expand All @@ -3277,17 +3356,28 @@ private void LoadMemory(MemoryReader mreader, Debugger debugger,
result = list;
}

private void LoadParsed(Debugger debugger, string name,
ContainerLoader loader,
private void LoadParsed(MemoryReader mreader, Debugger debugger,
string name, string type,
out List<double> result,
LoadCallback callback)
{
result = null;
List<double> values = new List<double>();
bool ok = loader.ForEachElement(debugger, name, delegate (string elName)
bool ok = containerLoader.ForEachElement(debugger, name, delegate (string elName)
{
if (!debugger.TryLoadDouble(elName, out double value))
return false;
double value = double.NaN;
if (valueLoader != null)
{
// TODO: what if the actual value is NaN?
value = valueLoader.Load(mreader, debugger, elName, valueType);
if (double.IsNaN(value))
return false;
}
else // no value loader found, assume it's built-in numeric type
{
if (!debugger.TryLoadDouble(elName, out value))
return false;
}
values.Add(value);
return callback();
});
Expand All @@ -3297,6 +3387,8 @@ private void LoadParsed(Debugger debugger, string name,
}

readonly ContainerLoader containerLoader;
readonly Value valueLoader;
readonly string valueType;
}

// This loader is created manually right now so LoaderCreator is not needed
Expand Down

0 comments on commit 48fba16

Please sign in to comment.