{"id":170,"date":"2014-04-02T21:39:02","date_gmt":"2014-04-03T04:39:02","guid":{"rendered":"http:\/\/visualgdb.com\/w\/?p=170"},"modified":"2023-03-29T17:57:30","modified_gmt":"2023-03-30T00:57:30","slug":"simplearrayvisualizer","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/w\/tutorials\/simplearrayvisualizer\/","title":{"rendered":"Making a type visualizer for a custom array class"},"content":{"rendered":"<p>In this tutorial we will create a type visualizer for our own vector-like array class. Before you begin, please follow the <a href=\"http:\/\/visualgdb.com\/SDK\/tutorials\/SimpleArrayVisualizer\/..\/VisualizerGettingStarted\/\">getting started<\/a> tutorial to make a very basic &#8220;dummy&#8221; visualizer and ensure that it works and can be debugged.<\/p>\n<ol>\n<li>Open the <strong>MyTypeVisualizer<\/strong> project (C# visualizer from the <a href=\"https:\/\/visualgdb.com\/w\/tutorials\/visualizergettingstarted\/\">previous tutorial<\/a>) and run it. A new instance of Visual Studio will start (and will be debugged by the first instance of Visual Studio).<\/li>\n<li>Open the C++ project from the previous tutorial and replace the main file with the following:\n<pre class=\"\">#include &lt;stdio.h&gt;\r\n#include &lt;assert.h&gt;\r\n\r\ntemplate &lt;class _Type&gt; class VeryBasicArray\r\n{\r\nprivate:\r\n    size_t m_Count;\r\n    _Type *m_pData; \r\n\r\npublic:\r\n    VeryBasicArray(size_t count)\r\n        : m_Count(count)\r\n       , m_pData(new _Type[count])\r\n    {\r\n    }\r\n\r\n    ~VeryBasicArray()\r\n    {\r\n       delete[] m_pData;\r\n    }\r\n\r\n    _Type &amp;operator[](size_t index)\r\n    {\r\n        assert(index &lt;= m_Count);\r\n       return m_pData[index];\r\n    }\r\n\r\n    size_t GetCount()\r\n    {\r\n       return m_Count;\r\n    }\r\n};\r\n\r\nint main()\r\n{\r\n    VeryBasicArray&lt;int&gt; test(3);\r\n    for (int i = 0; i &lt; test.GetCount(); i++)\r\n        test[i] = i * 100;\r\n    return 0;\r\n}<\/pre>\n<\/li>\n<li>Build the project. Place a breakpoint at the &#8220;return 0&#8221; line and start debugging. When the breakpoint is hit, hover the mouse over &#8220;test&#8221; to see its value:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/SimpleArrayVisualizer\/01-exp-basic.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/SimpleArrayVisualizer\/01-exp-basic.png\" alt=\"01-exp-basic\" width=\"395\" height=\"175\" \/><\/a>Notice how the value of &#8220;test&#8221; has been changed to &#8220;Hello, Visual Studio&#8221; by the basic visualizer from the previous tutorial.<\/li>\n<li>Carefully look at the values displayed by Visual Studio when you hover your mouse over &#8220;test&#8221; (or add it to the Watch window). Each tree node corresponds to the VisualGDB <a href=\"https:\/\/visualgdb.com\/reference\/extensibility\/html\/T_VisualGDBExpressions_IExpression.htm\">IExpression<\/a> interface. The annotated screenshot below shows which element of IExpression corresponds to the main displayed elements:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/SimpleArrayVisualizer\/02-expressiontree.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/SimpleArrayVisualizer\/02-expressiontree.png\" alt=\"02-expressiontree\" width=\"602\" height=\"212\" \/><\/a><\/li>\n<li>The type visualizers are based on the Expression Filter mechanism. Expression Filters can replace arbitrary <strong>IExpression<\/strong> objects with their own implementations. In most of the cases creating an instance of <a href=\"https:\/\/visualgdb.com\/reference\/extensibility\/html\/T_VisualGDBExpressions_StaticExpressionFilter.htm\">StaticExpressionFilter<\/a> and specifying which fields to override should be sufficient. We will now make a visualizer that will use the <strong>m_Count<\/strong> value to display the collection elements.<\/li>\n<li>The first step will be to query the <strong>m_Count<\/strong> value as an integer to know how many elements to query. Replace the body of the <strong>DoAttach()<\/strong> method with the following:\n<pre class=\"\">protected override IExpression DoAttach(IExpression expr,\r\n                                   IExpressionEvaluator evaluator)\r\n{\r\n    string countExpression = string.Format(\"({0}).m_Count\", expr.FullNameForEvaluator);\r\n    var value = evaluator.EvaluateExpression(countExpression, \"int\") as ExpressionValue.Integral;\r\n    if (value == null)\r\n        return null;\r\n\r\n    ulong count = value.Value;\r\n \r\n    return new StaticExpressionFilter(expr)\r\n    {\r\n        ValueOverride = new ExpressionValue.Custom(string.Format(\"An array with {0} items\", count))\r\n    };\r\n}<\/pre>\n<p><strong>Note that you can use &#8220;Break All&#8221; command in the outer Visual Studio to stop the inner Visual Studio, and then edit the visualizer code directly. Edit-and-continue will patch the visualizer on-the-fly, so you won&#8217;t need to restart Visual Studio or even restart the debugged C++ program!<\/strong><\/li>\n<li>Hover the mouse over &#8220;test&#8221; again. You will see the :<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/SimpleArrayVisualizer\/03-itemcount.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/SimpleArrayVisualizer\/03-itemcount.png\" alt=\"03-itemcount\" width=\"317\" height=\"107\" \/><\/a><\/li>\n<li>Note how we have queried the element count: first, we derived the GDB expression for it using IExpression.FullNameForEvaluator (would be &#8216;test.m_Count&#8217; in this case). Then we evaluated it using the <a href=\"https:\/\/visualgdb.com\/reference\/extensibility\/html\/T_VisualGDBExpressions_IExpressionEvaluator.htm\"> IExpressionEvaluator<\/a> interface. Finally we ensured that the returned value is a valid integral number (VisualGDB parses it automatically and returns <a href=\"https:\/\/visualgdb.com\/reference\/extensibility\/html\/T_VisualGDBExpressions_ExpressionValue_Integral.htm\"> ExpressionValue.Integral<\/a>) and extracted the integral value (of type <strong>ulong<\/strong>) from it.<\/li>\n<li>Now when we know the count and know that <strong>i<\/strong>-th element of the array can be accessed as <strong>test.m_pData[i] it&#8217;s<\/strong> time to create <strong>IExpression<\/strong> objects for all those values. Replace the return statement in the <strong>DoAttach()<\/strong> method with the following code:\n<pre class=\"\">List&lt;IExpression&gt; children =  new List&lt;IExpression&gt;();\r\nfor (ulong i = 0; i &lt; count; i++)\r\n{\r\n    string itemExpression = string.Format(\"({0}).m_pData[{1}]\", expr.FullNameForEvaluator, i);\r\n    var item = evaluator.CreateExpression(itemExpression);\r\n    if (item != null)\r\n        children.Add(item);\r\n}\r\n\r\nvar result = new StaticExpressionFilter(expr)\r\n{\r\n    ValueOverride = new ExpressionValue.Custom(string.Format(\"An array with {0} items\", count)) \r\n};\r\n\r\nresult.ChildrenOverride = new StaticChildProvider(children.ToArray());\r\nreturn result;<\/pre>\n<\/li>\n<li>Hover the mouse over &#8220;test&#8221; again:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/SimpleArrayVisualizer\/04-items.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/SimpleArrayVisualizer\/04-items.png\" alt=\"04-items\" width=\"413\" height=\"184\" \/><\/a><\/li>\n<li>The problem now is that the user won&#8217;t be able to access\/modify the original <strong>m_Count<\/strong> and <strong>m_Data<\/strong> values. To provide this possibility we will add an &#8220;Actual members&#8221; node. Instead of making our own implementation of <strong>IExpression<\/strong> we will simply reuse the <a href=\"https:\/\/visualgdb.com\/reference\/extensibility\/html\/T_VisualGDBExpressions_VirtualExpressionNode.htm\"> VirtualExpressionNode<\/a> class provided by VisualGDB:\n<pre>children.Insert(0, new VirtualExpressionNode(\"[Actual members]\",\r\n                                            \"\", expr.Children));<\/pre>\n<p>Note that we have simply &#8220;moved&#8221; the <a href=\"https:\/\/visualgdb.com\/reference\/extensibility\/html\/T_VisualGDBExpressions_IExpressionChildProvider.htm\"> IExpressionChildProvider<\/a> from the original expression node to the newly created node. We did not have to query any actual members at this point.<\/li>\n<li>Add the &#8220;test&#8221; to the Watch window and expand the results:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/SimpleArrayVisualizer\/05-actualmembers.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/SimpleArrayVisualizer\/05-actualmembers.png\" alt=\"05-actualmembers\" width=\"459\" height=\"215\" \/><\/a><\/li>\n<li>Note that the element names still have the format &#8220;(test).m_pData[i]&#8221; that corresponds to the raw GDB expressions, but is not very user-friendly. To fix this, we could wrap the child expressions returned by <a href=\"https:\/\/visualgdb.com\/reference\/extensibility\/html\/T_VisualGDBExpressions_IExpressionEvaluator.htm\"> IExpressionEvaluator<\/a>.<strong>CreateExpression()<\/strong> using <a href=\"https:\/\/visualgdb.com\/reference\/extensibility\/html\/T_VisualGDBExpressions_StaticExpressionFilter.htm\">StaticExpressionFilter<\/a> and override the ShortName.<\/li>\n<li>Furthermore, when dealing with a 1000-element array, our implementation would call <strong>CreateExpression()<\/strong> 1000 times even if the user just hovered the mouse over the array or had the &#8220;Autos&#8221; window open. To fix that we could make our own implementation of\u00a0<a href=\"https:\/\/visualgdb.com\/reference\/extensibility\/html\/T_VisualGDBExpressions_IExpressionChildProvider.htm\"> IExpressionChildProvider<\/a> creating child nodes on demand. To facilitate that VisualGDB provides the <a href=\"https:\/\/visualgdb.com\/reference\/extensibility\/html\/T_VisualGDBExpressions_ArrayChildProvider.htm\"> ArrayChildProvider<\/a> class that does everything automatically:\n<pre class=\"\">protected override IExpression DoAttach(IExpression expr,\r\n                                   IExpressionEvaluator evaluator)\r\n{\r\n     string countExpression = string.Format(\"({0}).m_Count\", expr.FullNameForEvaluator);\r\n     var value = evaluator.EvaluateExpression(countExpression, \"int\") as ExpressionValue.Integral;\r\n     if (value == null)\r\n         return null;\r\n \r\n     ulong count = value.Value;\r\n     var actualMembers = new VirtualExpressionNode(\"[Actual members]\", \"\", expr.Children);\r\n \r\n     var result = new StaticExpressionFilter(expr);\r\n \r\n     result.ValueOverride = new ExpressionValue.Custom(string.Format(\"An array with {0} items\", count));\r\n \r\n     string format = \"(\" + expr.FullNameForEvaluator + \").m_pData[{0}]\";\r\n \r\n     result.ChildrenOverride = new ArrayChildProvider(evaluator, format, 0, (int)count, actualMembers);\r\n     return result;\r\n }<\/pre>\n<\/li>\n<li>Delete &#8220;test&#8221; from the Watch window and add it once again:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/SimpleArrayVisualizer\/06-arraychildprovider.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/SimpleArrayVisualizer\/06-arraychildprovider.png\" alt=\"06-arraychildprovider\" width=\"459\" height=\"218\" \/><\/a><\/li>\n<li>You can get an overview of the raw commands that are being sent to GDB when your expressions are evaluated by selecting &#8220;All GDB interaction&#8221; in the GDB Session window:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/SimpleArrayVisualizer\/07-interaction.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/SimpleArrayVisualizer\/07-interaction.png\" alt=\"07-interaction\" width=\"660\" height=\"470\" \/><\/a><\/li>\n<\/ol>\n<h2>Source code<\/h2>\n<p>You can download the source code for the example in this tutorial <a href=\"http:\/\/sysprogs.com\/files\/visualgdb\/tutorials\/VisualizerTest-v2.zip\">here<\/a>. The code in the archive is provided under the BSD license (no restrictions, no warranty).<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial we will create a type visualizer for our own vector-like array class. Before you begin, please follow<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/170"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=170"}],"version-history":[{"count":11,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/170\/revisions"}],"predecessor-version":[{"id":8038,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/170\/revisions\/8038"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=170"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=170"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}