Archive for the ‘Geek Speak’ Category

Determining Allocated Memory in Delphi

Saturday, November 4th, 2006

One of the new features of BDS 2006 is a new memory manager. As a result, all of the old ways to get the amount of allocated memory have been deprecated. It is surprising to me that they did not give you an alternative way to get this information, but thanks to some searching of the FastMM code, here is a method to get the amount of allocated memory for your process.

function AllocatedMemory: Cardinal;
var
  MemoryManagerState: TMemoryManagerState;
  SmallBlockState: TSmallBlockTypeState;
begin
  GetMemoryManagerState(MemoryManagerState);
  Result := 0;
  for SmallBlockState in MemoryManagerState.SmallBlockTypeStates do
    Inc(Result, SmallBlockState.AllocatedBlockCount * SmallBlockState.UseableBlockSize);
  Inc(Result, MemoryManagerState.TotalAllocatedMediumBlockSize);
  Inc(Result, MemoryManagerState.TotalAllocatedLargeBlockSize);
end;

Change of plans

Thursday, January 26th, 2006

I was thinking of going to the Agile conference this year, but maybe I should go to the Waterfall conference instead.

To STAThread or not to STAThread

Wednesday, November 2nd, 2005

About a month ago at work, we started running to a “Failed to load resources from resource file” error when minimizing one of our applications. After some googling, all we were able to find is that no one really knows what causes the error, but removing the STAThread attribute fixes the issue. We removed the attribute and it appeared to work just fine, but now when you try to open a save dialog from the program on Windows 2000, it just hangs. So now we can put the attribute back in and have it crash when it is minimized, or we can have it hang when you launch save dialogs on Windows 2000. Gotta love Microsoft.

Rubyish collections in C# 2.0

Tuesday, October 11th, 2005

In the limited amount of time that I have played around with Ruby, I have been impressed with how easy it makes a lot of things. Utilizing the power of blocks, it is this simple to print out the contents of an array.

    list.each {|item| puts item}

C# 2.0 gives you something similar to blocks with the new anonymous methods. Say you want to show a message when a button is clicked. Before 2.0 you had to do quite a bit of coding to implement the feature.

First, you have to implement your method.

    private void button1_click(object sender, EventArgs e)
    {
        MessageBox.ShowMessage("Hello, World!");
    }

Then you have to assign the method to the click event.

   button1.Click +=  new System.EventHandler(button1_click);

With anonymous methods, this task becomes much simpler.

    button1.Click += delegate { MessageBox.Show("Hello, World!"); };

Granted, if you had a decent designer, most of this would be done automatically, but you can still see how much easier stuff like this is in C# 2.0.

After looking at the examples for anonymous methods, it got me thinking about whether you could implement methods on a list class similar to the way Ruby does. So I started by making a delegate method, and a descendent of ArrayList.

    delegate void EachDelegate(Object item);

    class MyCoolList: ArrayList
    {
        public void Each(EachDelegate delegateMethod)
        {
            foreach (object obj in this)
                delegateMethod(obj);
        }
    }

Now, to print out the contents to the command line.

    MyCoolList list = new MyCoolList();
    list.Add("foo");
    list.Add("bar");
    list.Add("baz");
    list.Each((EachDelegate)delegate(object obj) { Console.WriteLine(obj.ToString()); });

The syntax is a little ugly, but at least all of the code is there in the same method. Now that I have a class that implements each, lets look at leveraging generics to make the class, well more generic.

First we need to make our delegate generic.

    public delegate void EachDelegate<ReallyCoolListElement>(ReallyCoolListElement element);

Then we make our list class descend from List<T> and use the new generic delegate in our Each method.

    class MyReallyCoolList<ReallyCoolListElement> : List<ReallyCoolListElement>
    {
        public void Each(EachDelegate<ReallyCoolListElement> delegateMethod)
        {
            foreach (ReallyCoolListElement obj in this)
                delegateMethod(obj);
        }
    }

To use this new class we can modify the original code to look like this.

    MyRealyCoolList<string> list = new MyReallyCoolList<string>();
    list.Add("foo");
    list.Add("bar");
    list.Add("baz");
    list.Each((EachDelegate<string>)delegate(string element) { Console.WriteLine(element); });

Or if you wanted to use it to sum up a list of ints.

    int sum = 0;
    MyRealyCoolList<int> list = new MyReallyCoolList<int>();
    list.Add(1);
    list.Add(2);
    list.Add(3);
    list.Each((EachDelegate<int>)delegate(int element) { sum += element; });

The syntax in C# is not nearly as nice and sugary as Ruby, but this does demonstrate some of the cool new features that are being added to C# 2.0.

Installation Alternative?

Wednesday, October 5th, 2005

At work, we are using Wise as our installation solution. However, I have been very unhappy with the quality of their software. Many times when trying to get something to work in Wise, it comes to the point where you ask the question,”What is the stupidest thing that I could do to get this to work.” Usually the answer to that question is what we have ended up doing to get the features that we want. Sam and I have thought about trying to roll our own Delphi application to do the installation, but there are some features of Windows Installer that we would miss without a lot of extra work.

Anyway, enough of that rant. I was looking at an issue with Svn1ClickSetup where it was not installing TortoiseSVN into the correct directory, and I was trying to find out if I was using the wrong MSI property to set the install directory (that was the case BTW). So I started poking around the Tortoise source code, trying to find their installation code. I finally found some files that looked promising, but they had the extension .wxs, which I was not familiar with. Viewing the files, they looked like some sort of XML way to specify an installation. Interesting. So after some googling, I found this site. WiX is a toolset that Microsoft has released (open-source, no less) to allow you to describe your MSI using XML. There is also a Visual Studio plug-in for developing WiX scripts.

I don’t know how easy it is to create an installation using WiX, especially for an installation as complex as ours, but it looks like it could be a possible replacement for Wise. Since it uses XML to describe the installation, there is always the possibility of writing an application to generate the code. Definitely something that bears some more research.

Visual Studio + VSS = Nightmare

Monday, September 26th, 2005

At work, we are looking at replacing VSS with Subversion. One of the things that we need to do before porting over is to remove all of the shared files in VSS. A couple of weeks ago, I wrote a Ruby script to identify all of the shares, and after some modifications by Joe I have used it to start eliminating our mass of shared files.

This morning, Sam and I were getting rid of shares, and there were a couple of files shared between two solutions. At one point, there was probably a reason to have separate solutions, but that is no longer the case. Wanting to fold the two solutions together, we shared the files in VSS to the proper location, add the projects to the solution, and then delete the old solution. At this point, we get a clean image from VSS, and then re-open the solution thinking everything should work just fine. Not the case. Visual Studio says that the source control bindings are invalid for the projects that I just added. I really think that it is a bad idea to put dependencies on the source control system in the solution, but that’s a topic for another day.

One would think that changing bindings would be easy, so I open the bindings dialog, unbind the projects, and re-bind them to the solution directory just like all of the other projects that were working just fine. That didn’t work. Now it was telling me that the new paths were invalid. After fighting with Visual Studio for about fifteen minutes, I get an idea. Maybe it is the issue is because it can’t find the old location in VSS. So I go into VSS and recover the old solution. Back in Visual Studio, I unbind and re-bind again. Now one of the new projects is showing up as valid, but the second one still has the issue. Not feeling to happy with Microsoft at this point.

When Visual Studio fixed the binding for one project, it made changed the project file. After looking at the diffs, I open up the other project, and manually change the server bindings. After re-opening the solution, everything works just fine.

Needless to say, I was not too happy with Microsoft this morning. It’s pretty bad that you have to open up files in an editor and make the changes manually instead of changing them in the user-friendly GUI. Unfortunately, this seems to happen quite a bit, much more than it should.

Guide To Installing the Subversion HTTP Module on Windows

Tuesday, September 20th, 2005

After creating an installer to assist with setting up Subversion repositories on Windows, I started wondering how hard it would be to make a repository visible through HTTP. When comparing the different server configurations in the Subversion book they say that the HTTP server is “somewhat complex” to set up. Despite the warning that it was complex, I proceeded to get a repository up and running within a couple of hours (although it took me longer when I walked through my steps to write this guide for some reason). I thought that I would share my experience, and hopefully this guide will assist those you who would like to be able to use Subversion through HTTP.

  1. Download the binaries

    Go to the Apache download page and download the latest version of their web server. As of the writing of this article it was 2.0.54.

    Go to the Svn1ClickSetup download page and download the latest version. As of the writing of this article it was 0.8.3.

  2. Set up Subversion

    Run the Svn1ClickSetup executable downloaded in the previous step. When I refer to installation locations later in this guide, I will be assuming you installed everything in their default locations. If you install anything in a different directory, you will need to make the necessary adjustments.

    Note: Svn1ClickSetup installs a Subversion service, if you don’t want to be running this service, open a command prompt, and run the following command:

    svnservice -remove

  3. Install Apache

    Run the Apache installer that you downloaded. I had never installed Apache before, but the defaults worked fine for me.

    Once the installation finishes, launch a web browser, and browse to http://localhost. If you see a test page from Apache, the server is installed correctly.

  4. Set Up HTTP Access

    The first thing we need to do is make sure that Apache loads the WebDav modules. The Apache config file (httpd.conf) is located in the C:\Program Files\Apache Group\Apache2\ conf directory. Launch a text editor, and open the Apache config file. You will want to keep this file open for the rest of the installation.

    Copy the Subversion HTTP module (Program Files\Subversion\bin\mod_dav_svn.so) into the Apache modules directory (Program Files\Apache Group\Apache2\Modules).

    In the config file, look for a section of lines that all start with LoadModule. At the end of that section, add the following lines:

    LoadModule dav_module modules/mod_dav.so
    LoadModule dav_svn_module modules/mod_dav_svn.so
    

    At this point, restart the Apache2 service (Control Panel > Administrative Tools > Services). You will probably want to keep the Services window open (we will be restarting Apache several more times). If it restarts with no errors, Apache is now loading the SVN module.

    Back in the Apache config file, add the following to the end of the file:

    <Location /repos>
      DAV svn
      SVNPath "C:\svnrepos"
    </Location>
    

    Restart Apache2 again, and if it restarts successfully, go ahead and pat yourself on the back. You can now access your repository via HTTP (that wasn’t so bad, was it?)

  5. Configuring Authentication

    One small note before we start looking at authorization. There are several different ways you can configure authorization for Subversion, but I am only going to show you basic authorization in this guide. Basic authorization sends the passwords in near plain-text, so if you are concerned with password snooping, you will want to use a different authorization scheme.

    At this point, we can browse our repository via HTTP. Not only that, but we can also check-out, modify, and commit changes. However, none of these operations require any type of authorization. Not exactly what we want, especially if we are going to have multiple users.

    To enable authorization, we need to tell Apache who the authorized users are. To do this, we give Apache a file with a list of the authorized users and their passwords. Apache makes this job easy by providing a utility to mange the user file, htpasswd.

    Let’s go ahead and create our user file with the users Alice and Bob. We are going to put our file in the Apache conf directory, so open a command prompt to that directory (Program Files\Apache Group\Apache2\conf). Type the following command, and then enter a password for Alice.

    C:\Program Files\Apache Group\Apache2\bin\htpasswd -cm svn-auth-file Alice

    Now type in the following command to add Bob to the file.

    C:\Program Files\Apache Group\Apache2\bin\htpasswd -m svn-auth-file Bob

    Notice the difference between these two commands. The first command passes in the -c command, which tells htpasswd to create the file. The second time, the file already exists, so we don’t want it to be re-created. The second command is what you would use to add additional users to the file. If you look at the svn-auth-file, you will see entries for both Alice and Bob.

    Now that we have our authorization file, we need to tell Apache where to look for it. Go back to the Location tag that we added to the Apache config file. We need to add some more lines to it so that it looks like this

    <Location /repos>
      DAV svn
      SVNPath "C:\svnrepos"
      AuthType Basic
      AuthName "Subversion repository"
      AuthUserFile "C:\Program Files\Apache Group\Apache2\conf\svn-auth-file"
      Require valid-user
    </Location>
    

    After restarting Apache2 once again, browse to your repository again. This time, you will be prompted for a user name and password. Cool, we have authorization working. However, I don’t want to be prompted for a user name unless modifying the repository, so we’re not quite finished yet.

    Thankfully, only requiring authorization for modifications is really easy. All we have to do is add a couple more lines to our location tag so that it looks like this

    <Location /repos>
      DAV svn
      SVNPath "C:\svnrepos"
      AuthType Basic
      AuthName "Subversion repository"
      AuthUserFile "C:\Program Files\Apache Group\Apache2\conf\svn-auth-file"
      <LimitExcept GET PROPFIND OPTIONS REPORT>
        Require valid-user
      </LimitExcept>
    </Location>
    

    One last restart of Apache, and we now have the Subversion HTTP module installed, configured, and ready to control our revisions.

Any Significance?

Monday, September 12th, 2005

Looking at some test fixture code, there was one snippet that was passing in values to a test object. At first glance, the numbers seemed very random. But after looking at them some more, there may actually have been some thought behind them. So, your quiz for the day:

What is the significance of the numbers 5, 10, 7, 8, and 12?

Too many responsibilities

Thursday, September 8th, 2005

Sam and I have been working on a single story for about two weeks now (i.e. way to long). One of the things that we have done is refactored a class that had more responsibilities than any class has any right to have. Where there used to be one class, there are now about fourteen classes, and there are still at least five more begging to be created, but we will probably leave that for another day since we are already way over budget. Unfortunately, I have to admit that I was the original author of this monstrosity of a class.

One result of the refactoring that we have done is that it has shown me how much I have learned in the past year about not only what the single responsibility princple really means, but also, how to break these multi-responsibility classes into better factored code. SRP is not one object that drives an entire screen, but one that truly has just a single, small responsibility.

DUnit Scalability, or lack thereof

Wednesday, September 7th, 2005

At work, we use DUnit for our unit testing needs, but we have noticed that the GUI test runner is not very scalable at all. Right now, it takes around 60 times longer to run the tests from the GUI than it is to run them from a command-line test runner. To address the problem, I have replaced the TTreeView in the GUITestRunner with a Virtual Tree View, which makes a huge difference in performance.

In some simple testing scenarios, here is a comparison of performance. All of the tests simply contain

CheckTrue(True);

Running 1,000 tests:

  • GUITestRunner: 25 seconds
  • FastGUITestRunner: 2 seconds

Running 10,000 tests:

  • GUITestRunner: 4 minutes, 13 seconds
  • FastGUITestRunner: 17 seconds

As you can see, the DUnit test runner does not scale very well, and pleasently my new test runner seems to scale much better. If you want to take a look at the code, you can find it here.