VCmd script to compile current file and build a project

Useful for CUDA development, since VS somehow does not monitor the changes in CU files.

using EnvDTE;
using EnvDTE80;

public class Runner
{
    private const string PaneName = "VCmd";
    private DTE2 _dte;
    private int _step = 0;
    private OutputWindowPane _pane = null;
    private BuildEvents _buildEvents;

    public Runner(DTE2 dte)
    {
        _dte = dte;
        _buildEvents = dte.Events.BuildEvents;

        var panes = ((OutputWindow)_dte.Windows.Item(Constants.vsWindowKindOutput).Object).OutputWindowPanes;
        foreach (OutputWindowPane pane in panes)
        {
            if (pane.Name == PaneName)
            {
                _pane = pane;
                break;
            }
        }
        if (_pane == null)
        {
            _pane = panes.Add(PaneName);
        }
    }

    private void Log(string msg)
    {
        _pane.OutputString(String.Format("[{0:HH:mm:ss.fff}] {1}{2}", DateTime.Now, msg, Environment.NewLine));
    }

    public void Start()
    {
        Log("Script start..");
        _buildEvents.OnBuildDone += BuildEvents_OnBuildDone;
        _dte.ExecuteCommand("Build.Compile");
    }

    private void Build(string name)
    {
        var sol = _dte.Solution;
        foreach (Project proj in sol.Projects)
        {
            if (proj.Name == name)
            {
                sol.SolutionBuild.BuildProject(_dte.Solution.SolutionBuild.ActiveConfiguration.Name, proj.UniqueName, true);
                break;
            }
        }
    }

    private void BuildEvents_OnBuildDone(vsBuildScope Scope, vsBuildAction Action)
    {
        Log(String.Format("Script step {0}", _step));
        switch (_step)
        {
            case 0:
                _step = 1;
                Build("DependingProject");
                break;
            case 1:
                _dte.Events.BuildEvents.OnBuildDone -= BuildEvents_OnBuildDone;
                break;
        }
    }
}

public class C : VisualCommanderExt.ICommand
{
    private Runner _runner;
    public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package)
    {
        _runner = new Runner(DTE);
        _runner.Start();
    }
}

JavaScript event listener for history.pushState

In HTML there is an event onpopstate, but not onpushstate or onalterstate. How can we monitor such state changes? The answer is to alter the history.pushState function and manually dispatch an event inside.

More over, suppose we are writing a Chrome extension which has run_at: "document_start" that aims to capture all changes in states. Then we need to inject a <script> tag into the HTML, and we must do it as early as possible – right after the <head> tag is available. To achieve this we use a MutationObserver.

'use strict';

var observer = null;

function insertScript() {
    // script adapted from https://stackoverflow.com/a/25673911
    var s = '';
    s += 'var _wr = function(type) { var orig = history[type]; ';
    s += 'return function() { var rv = orig.apply(this, arguments);';
    s += 'var e = new Event(type); e.arguments = arguments; window.dispatchEvent(e);';
    s += 'return rv; }; };';
    s += 'history.pushState = _wr("pushState");';
    s += 'console.log("pushState altered")';

    var se = document.createElement('script');
    var head = document.getElementsByTagName('head')[0];
    se.innerHTML = s;
    head.insertBefore(se, null);
}

function observeHead() {
    observer = new MutationObserver(function(list) {
        for (var mutation of list) {
            if (mutation.addedNodes.length === 0) continue;
            var node = mutation.addedNodes[0];
            if (node.tagName !== 'HEAD') continue;

            observer.disconnect();
            insertScript();
            break;
        }
    });

    observer.observe(document, { childList: true, subtree: true });
}

observeHead();

window.addEventListener('pushState', function(ev) {
    console.log('pushState!');
});

The code for altering the pushState function comes from this StackOverflow answer

Ubuntu systemd start-up script

  1. Create a script, e.g. /root/startup.sh.
  2. Create a service in `/etc/systemd/system’, e.g. ‘/etc/systemd/system/startup.service’
  3. Edit the service:
[Unit]
Description=Startup Script

[Service]
Type=oneshot
ExecStart=/root/startup.sh
WorkingDirectory=/root

[Install]
WantedBy=multi-user.target

Lastly, run systemctl enable startup.service

Reboot and test.

Tips:

  1. Before adding the service, run the script to confirm that it works
  2. Before reboot, use service [name] start to confirm that it works

Optimizing C# reflection method calls

TL;DR: Func<> and Action<> instead of MethodInfo.Invoke runs 50 times faster

I can recall the excitement when I first learnt about reflection in C#. At that time my programming experience was limited to basic VB6 and C, so being able to browse type information was completely new to me. I was shocked and inspired by the possiblities that reflection can bring.

Reflection enables a lot of applications. For example, GameObject.SendMessage in Unity is fulfilled by finding the method with a name via reflection and then invoking it. Another important application is generic serializers. Without reflection, serializing objects will involve the pain of writing similar routines for every class[1]. Generic serializers like XmlSerializer and BinaryFormatter have saved a huge amount of development effort.

[1] Or some messy template and macro magic in C++ – see this StackOverflow answer for more.

However, we may overlook the performance cost as we enjoy the convenience. The rest of this post measures the reflection method calls in C#, and propose an optimization with delegate.

Continue reading Optimizing C# reflection method calls

Handling generic parameters in .Net dynamic code generation

In C#, it is possible to write code that generate dynamic assemblies, classes and methods at run time. This is a very powerful metaprogramming trick as it allows developers to generate IL instructions according to runtime situations. It also helps to reduce the size of an assembly by creating classes and methods only when needed. I heard that this approach is used to create XmlSerializer instances for better performance.

This article is not an introduction of how to do the magic (though it is fairly simple and you can learn from the skeleton code below without any difficulity). It explores a very specific situation when generic typing meets dynamic IL emitting.

Continue reading Handling generic parameters in .Net dynamic code generation

Draw curves in WPF efficiently

I have a customized canvas inheriting Canvas and overrides the OnRender(DrawingContext dc) method. And I need to draw some curves. I have precomputed the points on the curve and stored them in a List<Tuple<double, double>> because I am drawing different parts of the curve at different time. So, it is natural to come up with

for (int i = start; i <= end; ++i)
{
    dc.DrawLine(CurvePen, new Point(list[i].Item1, list[i].Item2), new Point(list[i+1].Item1, list[i+1].Item2));
}

However this approach is slow and CPU-intensive as hell. Guess what? I had a naive test and wrote

var gstr = new StringBuilder();
gstr.Append($"M {list[start].Item1},{list[start].Item2} L ");
for (int i = start + 1; i <= end; ++i)
{
    gstr.Append($"{t.Item1},{t.Item2} ");
}
dc.DrawGeometry(null, CurvePen, Geometry.Parse(gstr.ToString()));

Basically the code constructs a Path Markup, parse it to a Geometry object and draw it. It looks terrible – that’s a lot of string operations… but it is actually very, very fast. In fact, much faster than the multiple DrawLine calls.

One possible optimization is to, apparently, precompute all the Geometry objects, although it may result in worse performance because that’s a lot of objects. So I’ll just stick to this construct-on-the-fly thing at the moment 😛