Skip to content

Commit 48fba16

Browse files
committed
Add Value loader and add support for C++ std::chrono::duration
1 parent 251e6d5 commit 48fba16

File tree

2 files changed

+114
-22
lines changed

2 files changed

+114
-22
lines changed

solution/GraphicalDebugging/Debugger.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public bool TryLoadDouble(string name, out double result)
3737
{
3838
result = 0.0;
3939
string castedName = !IsLanguageBasic
40-
? "(double)" + name
40+
? "(double)(" + name + ")"
4141
: "CType(" + name + ", Double)";
4242
var expr = debugger.GetExpression(castedName);
4343
return expr.IsValidValue

solution/GraphicalDebugging/ExpressionLoader.cs

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

1111
using System;
1212
using System.Collections.Generic;
13+
using System.Runtime.InteropServices.WindowsRuntime;
1314
using System.Threading.Tasks;
1415

1516
namespace GraphicalDebugging
@@ -35,7 +36,7 @@ public enum Kind
3536
Container = 0, MultiPoint, TurnsContainer, ValuesContainer, GeometriesContainer,
3637
Point, Segment, Box, NSphere, Ray, Line, Linestring, Ring, Polygon,
3738
MultiLinestring, MultiPolygon, MultiGeometry, Turn, OtherGeometry,
38-
Variant, Image
39+
Variant, Image, Value
3940
};
4041

4142
public delegate void BreakModeEnteredEventHandler();
@@ -111,6 +112,8 @@ private ExpressionLoader(DTE2 dte)
111112
loadersCpp.Add(new StdPairPoint.LoaderCreator());
112113
loadersCpp.Add(new StdComplexPoint.LoaderCreator());
113114

115+
loadersCpp.Add(new StdChronoDuration.LoaderCreator());
116+
114117
loadersCpp.Add(new BVariant.LoaderCreator());
115118

116119
loadersCpp.Add(new StdArray.LoaderCreator());
@@ -231,7 +234,7 @@ public bool Check(Kind kind)
231234
private readonly Kind mKind;
232235
}
233236

234-
public class NonValueKindConstraint : IKindConstraint
237+
public class NonValueContainerKindConstraint : IKindConstraint
235238
{
236239
public bool Check(Kind kind)
237240
{
@@ -242,7 +245,11 @@ public bool Check(Kind kind)
242245

243246
public class DrawableKindConstraint : IKindConstraint
244247
{
245-
public bool Check(Kind kind) { return kind != Kind.Container; }
248+
public bool Check(Kind kind)
249+
{
250+
return kind != Kind.Container
251+
&& kind != Kind.Value;
252+
}
246253
}
247254

248255
// IMPORTANT: GeometriesContainer cannot be a Geometry,
@@ -254,7 +261,8 @@ public bool Check(Kind kind)
254261
return kind != Kind.Container
255262
&& kind != Kind.ValuesContainer
256263
&& kind != Kind.GeometriesContainer
257-
&& kind != Kind.Image;
264+
&& kind != Kind.Image
265+
&& kind != Kind.Value;
258266
}
259267
}
260268

@@ -264,7 +272,8 @@ public bool Check(Kind kind)
264272
{
265273
return kind != Kind.Container
266274
&& kind != Kind.ValuesContainer
267-
&& kind != Kind.Image;
275+
&& kind != Kind.Image
276+
&& kind != Kind.Value;
268277
}
269278
}
270279

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

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

3192+
// TODO: Add abstract class and derive from it here
3193+
// TODO: Add user-defined Calue in ExpressionLoader_UserDefined
3194+
class Value : Loader
3195+
{
3196+
public Value(string memberName, string memberType)
3197+
{
3198+
this.memberName = memberName;
3199+
this.memberType = memberType;
3200+
}
3201+
3202+
public double Load(MemoryReader mreader, Debugger debugger, string name, string type)
3203+
{
3204+
// TODO: what if the actual value is NaN?
3205+
return debugger.TryLoadDouble(name + "." + memberName, out double result)
3206+
? result
3207+
: double.NaN;
3208+
}
3209+
3210+
public MemoryReader.Converter<double> GetMemoryConverter(MemoryReader mreader,
3211+
Debugger debugger, // TODO - remove
3212+
string name,
3213+
string type)
3214+
{
3215+
string member = name + "." + memberName;
3216+
if (!debugger.GetAddressOffset(name, member, out long memberOffset)
3217+
|| !debugger.GetTypeSizeof(member, out int memberSize))
3218+
return null;
3219+
MemoryReader.ValueConverter<double> memberConverter = mreader.GetNumericConverter(memberType, memberSize);
3220+
return memberConverter != null
3221+
&& debugger.GetTypeSizeof(type, out int sizeOfValue)
3222+
&& !Debugger.IsInvalidOffset(sizeOfValue, memberOffset)
3223+
? new MemoryReader.StructConverter<double>(
3224+
sizeOfValue,
3225+
new MemoryReader.Member<double>(memberConverter, (int)memberOffset))
3226+
: null;
3227+
}
3228+
3229+
private readonly string memberName;
3230+
private readonly string memberType;
3231+
}
3232+
3233+
class StdChronoDuration : Value
3234+
{
3235+
public class LoaderCreator : ExpressionLoader.ILoaderCreator
3236+
{
3237+
public bool IsUserDefined() { return false; }
3238+
public Kind Kind() { return ExpressionLoader.Kind.Value; }
3239+
public Loader Create(Loaders loaders, Debugger debugger, string name, string type, string id)
3240+
{
3241+
if (id != "std::chrono::duration")
3242+
return null;
3243+
3244+
List<string> tparams = Util.Tparams(type);
3245+
if (tparams.Count < 1)
3246+
return null;
3247+
3248+
return new StdChronoDuration("_MyRep", tparams[0]);
3249+
}
3250+
}
3251+
3252+
private StdChronoDuration(string memberName, string memberType) : base(memberName, memberType)
3253+
{}
3254+
}
3255+
31833256
class ValuesContainer : LoaderR<ExpressionDrawer.ValuesContainer>
31843257
{
31853258
public class LoaderCreator : ExpressionLoader.ILoaderCreator
@@ -3201,17 +3274,19 @@ public Loader Create(Loaders loaders, Debugger debugger, string name, string typ
32013274
containerLoader.ElementInfo(name, type, out string elName, out string elType);
32023275

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

3206-
return l == null // this is not non-value
3207-
? new ValuesContainer(containerLoader)
3279+
return l == null ? new ValuesContainer(containerLoader, null, elType)
3280+
: l is Value ? new ValuesContainer(containerLoader, l as Value, elType)
32083281
: null;
32093282
}
32103283
}
32113284

3212-
private ValuesContainer(ContainerLoader containerLoader)
3285+
private ValuesContainer(ContainerLoader containerLoader, Value valueLoader, string valueType)
32133286
{
32143287
this.containerLoader = containerLoader;
3288+
this.valueLoader = valueLoader;
3289+
this.valueType = valueType;
32153290
}
32163291

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

32403315
if (mreader != null)
3241-
LoadMemory(mreader, debugger, name, type, containerLoader, out result, callback);
3316+
LoadMemory(mreader, debugger, name, type, out result, callback);
32423317

32433318
if (result == null)
3244-
LoadParsed(debugger, name, containerLoader, out result, callback);
3319+
LoadParsed(mreader, debugger, name, type, out result, callback);
32453320

32463321
return result;
32473322
}
32483323

32493324
private void LoadMemory(MemoryReader mreader, Debugger debugger,
32503325
string name, string type,
3251-
ContainerLoader loader,
32523326
out List<double> result,
32533327
LoadCallback callback)
32543328
{
32553329
result = null;
32563330

3257-
loader.ElementInfo(name, type, out string elemName, out string elemType);
3331+
containerLoader.ElementInfo(name, type, out string elemName, out string elemType);
32583332

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

3262-
MemoryReader.ValueConverter<double>
3336+
MemoryReader.Converter<double> valueConverter = null;
3337+
3338+
if (valueLoader != null)
3339+
valueConverter = valueLoader.GetMemoryConverter(mreader, debugger, elemName, elemType);
3340+
else
32633341
valueConverter = mreader.GetNumericConverter(elemType, valSize);
3342+
32643343
if (valueConverter == null)
32653344
return;
32663345

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

3280-
private void LoadParsed(Debugger debugger, string name,
3281-
ContainerLoader loader,
3359+
private void LoadParsed(MemoryReader mreader, Debugger debugger,
3360+
string name, string type,
32823361
out List<double> result,
32833362
LoadCallback callback)
32843363
{
32853364
result = null;
32863365
List<double> values = new List<double>();
3287-
bool ok = loader.ForEachElement(debugger, name, delegate (string elName)
3366+
bool ok = containerLoader.ForEachElement(debugger, name, delegate (string elName)
32883367
{
3289-
if (!debugger.TryLoadDouble(elName, out double value))
3290-
return false;
3368+
double value = double.NaN;
3369+
if (valueLoader != null)
3370+
{
3371+
// TODO: what if the actual value is NaN?
3372+
value = valueLoader.Load(mreader, debugger, elName, valueType);
3373+
if (double.IsNaN(value))
3374+
return false;
3375+
}
3376+
else // no value loader found, assume it's built-in numeric type
3377+
{
3378+
if (!debugger.TryLoadDouble(elName, out value))
3379+
return false;
3380+
}
32913381
values.Add(value);
32923382
return callback();
32933383
});
@@ -3297,6 +3387,8 @@ private void LoadParsed(Debugger debugger, string name,
32973387
}
32983388

32993389
readonly ContainerLoader containerLoader;
3390+
readonly Value valueLoader;
3391+
readonly string valueType;
33003392
}
33013393

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

0 commit comments

Comments
 (0)