Archive for August, 2006

Sony EyeToy on Windows

August 2006 – August 2007 Hardware (, ) • 807 views • no response

I got a new silver Sony EyeToy for my birthday (along with the EyeToy 3 games, thanks Amy!) and found that it didn’t want to play with Windows.

The earlier black model worked just fine with a modified INF file and so it was back to notepad to slip in the required lines.

Rather than give instructions on messing round with downloading other people’s drivers and editing .inf files I’ve just packed it all up.

Download Sony EyeToy drivers (Windows) (404KB)

[)amien

XNA Game Studio Express out today

August 2006 – March 2008 .NET (, ) • 969 views • no response

Beta 1 of Microsoft’s free XNA Game Studio Express product should be available for download later today.

If you haven’t already got started you’ll need to download the following bits first:

Then sign up for the beta and come hang out in the IRC channel #xna on irc.quakenet.org.

Update

XNA Game Studio Express is now available for download!

[)amien

Choose your ORM: Runtime, code generation or build provider?

August 2006 – March 2008 .NET (, , , ) • 1,446 views • one response

Selecting the right object-relational mapper is a tricky decision with many factors to weigh up.

One of the basic decisions is whether to go with a dynamic runtime (“black-box”) or a code generator.

I’m not a fan of the runtime approach – the discovery at runtime negatively impacts performance as it often uses reflection (or failing that post-compilation byte code modification) whilst robbing you of compile-time checking, IntelliPrompt support against your database objects, deployment and potentially licensing issues. In effect, it’s not that much better than a typed dataset.

Code generation provides for a much finer granularity letting you tweak the templates for the performance and features you need whilst also providing full compile-time checking and IntelliPrompt support.

Tools such as CodeSmith (my personal favourite), MyGeneration (free) do a good job of letting you write these templates and create the necessary ORM code but require being re-run every time you change the schema. During the starting phases of a project this could be quite often and goes against the whole concept of RAD.

So step in SubSonic and it’s build provider approach.

The idea here is that you modify your .config file to include the SubSonic build provider and it’s connection string, drop a simple text file in that lists which tables to work with and you’re done.

SubSonic now goes off to your database via the connection and generates all the code for tables you need and it’s magically there to be used like any other classes. Check out the demo to see just how easy it is.

SubSonic supports a large number of databases, has support for Enterprise Library, is open source and also provides simple “scaffold” pages that let you throw a basic web add/edit/update/delete table maintenance page by just throwing a table name attribute onto an empty page’s form element.

The only downside at this point is that it uses the ActiveRecord pattern for the ORM. If I manage to get some time to spend with it and can knock up a Domain Object + Data Mapper version I’ll let you know.

[)amien

Equatable Weak References

August 2006 – April 2010 .NET (, ) • 1,950 views • no response

In a previous post I described a WeakReference<T> class for providing strongly-typed WeakReference objects.

One problem with the previous WeakReference<T> class is being able to use and find it within the various collection classes. This is because one WeakReference<T> is not equal to another WeakReference<T> class.

Overriding the Equals method fixes this problem at first glance however also reveals another issue.

If you override Equals you should also override the GetHashCode method so that two objects that equal each other return the same hash code. This is because some of the collection classes use hash codes to efficiently lookup items within their collection.

Normally a hash code would be calculated from the various data items that comprise the class but in our case we really only have one to go on – the Target object itself. This raises two more issues:

  1. The hash code should not change over the objects lifetime – difficult when your Target object can be changed.
  2. The hash code should be stored because the Target object might well be collected by the GC – after all that’s what this class is all about.

This doesn’t leave us with many choices at all.

We must grab the hash code from the Target object within our constructor and store it for subsequent retrieval.

Here is EquatableWeakReference<T> with the usual disclaimers as to it’s suitability for any purpose.

using System;
using System.Runtime.InteropServices;

public class EquatableWeakReference<T> : IEquatable<EquatableWeakReference<T>>, IDisposable where T : class
{
    protected GCHandle handle;
    protected int hashCode;

    public EquatableWeakReference(T target) {
        if (target == null)
            throw new ArgumentNullException("target");
        hashCode = target.GetHashCode();
        InitializeHandle(target);
    }

    protected virtual void InitializeHandle(T target) {
        handle = GCHandle.Alloc(target, GCHandleType.Weak);
    }

    ~EquatableWeakReference() {
        Dispose();
    }

    public void Dispose() {
        handle.Free();
        GC.SuppressFinalize(this);
    }

    public virtual bool IsAlive {
        get { return (handle.Target != null); }
    }

    public virtual T Target {
        get {
            object o = handle.Target;
            if ((o == null) || (!(o is T)))
               return null;
            else
               return (T)o;
            }
    }

    public override bool Equals(object other) {
        if (other is EquatableWeakReference<T>)
            return Equals((EquatableWeakReference<T>)other);
        else
            return false;
    }

    public override int GetHashCode() {
        return hashCode;
    }

    public bool Equals(EquatableWeakReference<T> other) {
        return ReferenceEquals(other.Target, this.Target);
    }
}

[)amien