Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Converting Enumerations to User Readable Strings in .NET

Suppose you have the following scenario: You have a function that can return multiple return types codes via an enum value. For each of those enum values, you want to inform the user the result of the operation by some user friendly string.

A common implementation I see is some sort of switch statement that resolves enumerations to a string by way of a switch statement or hash table or something. And whenever that string is needed, call into said method.

And although this is viable, this creates a disconnect between the enum and it’s actual string literal definition. In addition, for each new enumeration value, that giant switch statement needs to be updated with a new string value. If there were only a clean way to map an enum to a string value automatically… and there is! With clever usage of attributes, reflection, and extension methods, one can do something like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace EnumString
{
[AttributeUsage(AttributeTargets.Field)]
class EnumStringAttribute : Attribute
{
string myValue;
public EnumStringAttribute(string value)
{
myValue = value;
}

public override string ToString()
{
return myValue.ToString();
}
}

static class ExtensionMethods
{
public static string ToUserString(this Enum enumeration)
{
var type = enumeration.GetType();
var field = type.GetField(enumeration.ToString());
var enumString = (from attribute in field.GetCustomAttributes(true) where attribute is EnumStringAttribute select attribute).FirstOrDefault();
if (enumString != null)
return enumString.ToString();
return enumeration.ToString();
}
}

enum AuthenticationResult
{
[EnumString("This username is not registered.")]
NotRegistered,
[EnumString("Incorrect password.")]
BadPassword,
[EnumString("Logging in...")]
Success,
}

class Program
{
static void Main(string[] args)
{
Console.WriteLine(AuthenticationResult.BadPassword.ToUserString());
Console.WriteLine(AuthenticationResult.NotRegistered.ToUserString());
Console.WriteLine(AuthenticationResult.Success.ToUserString());
}
}
}

Delaring string values can simply be done inline, and the usage is simple as well! Just call the new extension method to get your user friendly string!

(Of course, for localization, you may want to map the enum to a string resource rather than a hard coded string value; but a similar approach can be used.)

Learn Something New Every Day...

Recently I started jotting down anything new that made me say "oh cool!". Some are rarely used C# language features, some are API mechanics, and some are just random trivia. Here's what I've come up with so far:

C#'s stackalloc Keyword

stackalloc is basically handy way to allocate an array on the stack and can provide several conveniences.

Instead of allocating a locally scoped array (which is backed by the heap and managed by the garbage collector), you can get better "bare metal" performance by using stackalloc:

float SomeFunction(float[] input)
{
float dataResults;
float[] data = new float[3];
// we are calculating a result from input and storing interim results in data
return dataResults;
}

At the end of this method, a float array is sitting around waiting to be garbage collected. Instead, that function can become:

unsafe float SomeFunction(float[] input)
{
float dataResults;
float* data = stackalloc float[3];
// do something with the data and input
return dataResults;
}

In addition to taking the garbage collector and heap allocation out of the equation to eek out a little more performance, you also get a native float pointer. This can make interop with unmanaged code quite friendly, rather than a giant mess of fixed statements that would come about as a result of using float arrays.

 

C#'s ?? operator

Consider the following method:

Foo EnsureNotNull(Foo foo)
{
if (foo != null)
return foo;
return new Foo();
}

You can trim that down a bit by using a ternary operator:

Foo EnsureNotNull(Foo foo)
{
return foo == null ? new Foo() : foo;
}

But why use that when ?? is a binary null check operator; I.e., it returns the left if it is not null and the right otherwise:

Foo EnsureNotNull(Foo foo)
{
return foo ?? new Foo();
}

 

Hardware Graphics Acceleration and Asynchronous Calls

This is a tip I learned way back in my hay day of amateur game development. Many OpenGL/Direct3D may be just asynchronous calls on the hardware, and subsequent operations may end up resulting in them waiting for the previous operation to finish. The following is a very common pattern in drawing routines:

void OnPaint()
{
glClear(GL_COLOR_BUFFER_BIT);
// paint a bunch of stuff
// glDrawStuff();
glSwapBuffers();
}

Here, the code is immediately making paint operations following the clear. This results in those operations waiting until the clear has completed before executing. Restructuring the code as follows can squeeze out a little more performance:

void OnPaint()
{
// paint a bunch of stuff
// glDrawStuff();
glSwapBuffers();
// clear the buffer after the background and foreground are swapped
// this clear will take place asynchronously and be complete
// when we start to draw the next frame!
glClear(GL_COLOR_BUFFER_BIT);
}

I implemented this in GLMaps recently, and saw an FPS increase from 49 to 51. That's a ~4% increase! Using this technique, any static preprocessing/setup can actually just be run at the end of the drawing operations, rather than at the beginning. (Concurrently using the CPU and GPU between frames to get a net gain in FPS)

 

Handy C# 3.0 Shorthand

This tip didn't actually catch me by surprise, since I read through the C# 3.0 new features. However, old habits die hard, so I often forget to use them. Prior to C# 3.0, the following would be a standard class declaration:

class Foo
{
int myBar;
public int Bar
{
get
{
return myBar;
}
set
{
myBar = value;
}
}

double myMoo;
public double Moo
{
get
{
return myMoo;
}
private set
{
myMoo = value;
}
}

float myCool;
private float Cool
{
get
{
return myCool;
}
set
{
myCool = value;
}
}
}

With C# class declaration shorthand, developers can now eliminate much of the redundancy (the properties and backing fields are implicitly defined):

class Foo
{
public int Bar
{
get;
set;
}

public double Moo
{
get;
private set;
}

public float Cool
{
get;
set;
}
}

Also, when declaring an instance of that class, prior to C# 3.0, a common pattern is to set some initial properties:

void MakeFoo()
{
Foo foo = new Foo();
foo.Bar = 0;
foo.Cool = 0;
}

With C# 3.0, you get additional shorthand (less characters, not lines), and a more aesthetically pleasing syntax:

void MakeFoo()
{
Foo foo = new Foo()
{
Bar = 0,
Cool = 0
};
}

 

That's it for tips for now. Share 'em if you got 'em!

Microsoft's DLR and Mono bring Python and Ruby to Android

device

With my recent work on porting Mono to Android, I began needing a way to create Java classes and invoke their various methods from C#. I had read briefly about the Dynamic Language Runtime and upcoming C# support for dynamic types; so that naturally led to me considering implementing a JNI-P/Invoke interop layer that allows access to Java/Dalvik code through C# and vice versa. However, I wasn't sure if the DLR would even run on Mono, but I was pleasantly surprised. Support for the DLR was added to Mono around a year and a half ago!

After copying the necessary DLLs over to the phone, I was able to run the simple ipy.exe console application that comes with the DLR source code. The neat thing I discovered while perusing through the documentation is that IronRuby and IronPython are actually compiled into CIL byte code and thus eventually native code! Anyhow, as you can see, IronPython is working dandily on the phone. [1]

The Dynamic Language Runtime is probably the coolest new toy in the .NET arsenal since lambda expressions. Couple the DLR with the new dynamic keyword in C# 4.0, and you can invoke dynamic languages from C# as easily as you can access .NET classes from IronPython or IronRuby![0]

Now to get back to implementing Java interop...

 

[0] The dynamic keyword basically provides compile time parsing of an expression tree, but the expression isn't actually validated until runtime.

[1] Though Mono + DLR is clocking in at a hefty 13mb in files. But, applications will soon be installable onto the SD card so the storage constraints will be a moot point.

C# 4.0! Visual Studio 2010 CTP!

Can't believe I missed this release... There's a lot of exciting new features upcoming in the .NET front. My personal favorites:

  • IDynamicObject and C# 4.0: C# can now has native/syntactic support for dynamic objects that may come from JavaScript, IronRuby, IronPython, COM, etc. Pretty awesome!
  • Optional Parameters: Remember the good ol' days of C++ where you could define optional parameters with default values set for you? Yeah, they're back. I imagine that some changes had to be made to the type system/reflector; I'm curious as to how this works under the hood.

Click here to download the Visual Studio 2010 and .NET Framework 4.0 CTP.

And here's some documentation and code samples for the new features in C# 4.0.

Note: Ugh, the CTP is a Virtual PC instance. Guess I'll have to wait till they have a installable version, or maybe just convert the instance to HyperV...

Post 11: Android versus Windows Mobile Development

I wanted to refrain from blogging about this until I had at least somewhat delved into Android development. And although I am by no means a guru at the Android platform yet, I feel I can safely make some broad statements, step on some toes, and be able to sufficiently back up my opinions. [0] :)

 

The Byte Code

Google made some interesting architectural and strategic decisions regarding Android. The most notable being Java as the development language and Dalvik as the underlying bytecode. Dalvik, in short, is a byte code that is interpreted at runtime, similar to Sun's Java byte code or Microsoft's Intermediate Language (aka IL)[1]. I didn't really understand why Google would go and create another byte code specification for Java until I read a great article by Stefano Mazzochi. The long and short of it is, Sun has some nasty licensing around Java ME, and the "Open" Handset Alliance can't really have an Open platform with the possibility of some mega-corporation trying to wet their beaks at their expense. [2]

So, still begs the same question: why invent a whole new byte code when Intermediate Language has no such licensing (it is an ECMA approved standard)?  Maybe Google took a look at it and decided it wasn't suitable for a mobile platform, or maybe they didn't want to jump into bed with Microsoft. I'm guessing the latter.

 

The Language

At the end of the day, the byte code generated behind the scenes is about as important as the color of my socks. I generally don't think about it on a daily basis, and what really matters is the language you are writing in. I can understand that Google chose Java to ease their target developer base's transition the new platform, but still... I'm going to just go ahead and say it. Java sucks.

How much does Java suck? Let me count the ways.

  1. Terrible constraints around package/file/directory/class names.
  2. Lack of anonymous methods.
  3. Lack of closures.
  4. No lambda expressions (or LINQ).
  5. Lack of events/delegates.
  6. Lack of partial classes.
  7. Ridiculous implementation of enumerations.
  8. Terrible implementation of generics (type erasure).
  9. No user defined value-types: no "struct" and thus no capability of having objects that live purely on the stack. This is nasty on performance when it counts (such as in games).
  10. Strings are immutable, but not interned.
  11. No access to "unsafe" code.
  12. No get/set accessor methods.
  13. No operator overloading.
  14. No extension methods.
  15. Last but not least, stupid and unintuitive brace positioning.

How many ways? 13, 14, 15, Ha, Ha, Ha, Ha, Ha!

 

I'm not trying to be a nit-picky zealot here; everything I listed is a feature I use on a regular basis. I will admit though, that I am enjoying anonymous classes to some degree, but they would be mostly pointless with the availability of events/delegates. I realize that most of what I listed is just syntactic sugar, and neither Java or C# is more "powerful" than the other; they can each do anything you need in their own way. Except C# lets you do it more quickly, intuitively, and elegantly. [3]

 

The Development Environments

Eclipse is a giant steaming pile of... yeah. Yes, very capable, very flexible, but whoever is doing usability testing on this junk needs to get a job that involves testing the constricting force of a rope around their neck.

My biggest pet peeve is the fact that you can't simply click in the Expressions view and edit or add something inline. You have to right click it and click add/edit. That takes you to a vanilla text editor (which has no Intellisense/Content Assist), type in your expression, pray it is parsable, and then click ok. Otherwise you are having to go through that zillion step process yet again.

Earlier I gave some kudos to Java's inner class capabilities. As neat as they are, Eclipse makes them damn near unusable: you can't watch a value of a member variable in the parent class of an inner class. That makes debugging a giant pain: you need to load all those members into local variables if something is going wrong, otherwise it is impossible to find and fix even simple issues, such as a null reference. I'm not sure if this is a problem with Eclipse, Java, or Android though.

The auto-complete in Eclipse is painfully annoying. Auto-complete should be optional, and not forcibly inserted with no regard to what the developer wants. I ended up turning it all off, because what it was inserting was generally useless. And even though the auto-complete is off, Eclipse is still inserting parenthesis for me...

 

The SDKs 

Though I have been complaining a lot about developing on Android, I do want to point out that I haven't actually complained about Android. Basically every API I could think of was standardized and implemented.

My litmus test in this regard was a port of Klaxon to Android. It really helped underscore the huge differences between the two platforms.

For me, most notable was the APIs to access device sensors. Version 1 of the Android SDK exposes a simple SensorManager class that took me 5 minutes to figure out and access. Microsoft has had 6ish versions of Windows Mobile with no Sensor API in sight.

Secondly, scheduling processes to start on Android is infinitely easier than in Windows Mobile. Here's how that learning process worked for me on Windows Mobile:

  • First I started with CeRunAppAtTime. I write a gross PInvoke for this. This works for a while, then stops working completely. Others have had this issue as well. I need to switch to another mechanism.
  • Then I switched to CeSetUserNotificationEx. I write yet another gross PInvoke for this.
  • This involves filling out some elaborate UserNotificationTrigger structure. I eventually get this working.
  • Then I find that if the device is sleeping, Klaxon sometimes does not start properly.
  • I solve this issue by digging through some documentation and randomly figuring out the problem: I need to force the device to turn on or it goes back to sleep.
  • Klaxon works again for a while, until daylight savings occurs. On some phones, it is now firing an hour late. I have no idea why. I have given up.

Let's compare this to Android:

  • Access the AlarmManager.
  • Tell it to turn on and fire an intent at a certain time.
  • Handle the intent.

This just works, no hassle, no fuss. I must say, intents are easy to use, amazingly flexible, and equally powerful.

So, two of the "difficult" parts for creating Klaxon on Windows Mobile were not so difficult at all on Android. The final piece: UI implementation.

Windows Forms code versus Android's XML Layout. Windows Forms which works with absolute sizing and positioning, and Android which uses relative sizing and positioning. Windows "Static" Controls versus Android's Animatable Controls. There really is no comparison, so I won't even bother.

Simply put, the relevant Android SDK blows the Windows Mobile SDK out of the water (language and framework features aside).

Windows Mobile does have far better documentation (MSDN) than Android, but I consider that more of a teething issue that would occur with any new SDK.

 

The Platforms

Android is pretty heavily locked down from a security standpoint. Applications must register what capabilities they wish to have, and the user must approve of them. And though this security is all in all a positive thing, it does have it's downsides; for example, it is impossible to write an application that screen shots a screen other than its own, as this is considered a security risk. [4]

And though this is not really a fault of Android per se, the phones that are actually being released are not as "open" as the name Open Handset Alliance would suggest. Carriers always have and will continue to lock down phones so long as they subsidize them. For example, the user does not have access to the root account on the G1; this makes removal/tweaking of the standard Android applications impossible. But at least on Android you can tweak the standard applications due to it being open source (after getting root).

On the flip side of the coin, Windows Mobile doesn't have a VM hiding all the nitty gritty details from you. Developers can easily get low level access to anything, without having to worry about Microsoft filling the holes. For example, if Android were to have shipped without a Sensor API, there is no way (outside of manually installing native binaries through ADB) that a developer could implement it. And that is not a comforting feeling. For example: Android does not support streaming video through the MediaPlayer yet, and as far as I know, nothing can be done about that unless the native android binaries are patched through an OTA update.

Oh, and the Android Market. Not going to bother elaborating on this point, as the statement itself is pretty self explanatory.

 

Summary

I don't really have anything insightful to say here, and that may be because it is 4AM. I'll wrap it up by saying, I really enjoy developing for Windows Mobile. The language and tools are great. However, the platform and applications simply are not very usable. On the other hand, though I'm not completely discontent with Android development, the platform, applications, and general usability is fantastic; for once I don't have to fight my phone to do simple things like browse the web. So you can guess which phone is always in my pocket. And then you can infer which once I am more interested in developing in.

That said, I hope Microsoft can produce a usable platform in the near future; as that would make me a very happy user and developer. I can't believe I'm going to say this, but they should take a page out of Apple's book and just say "screw backwards compatibility, screw existing applications, we're going to develop a brand new platform that works". They've been catering to the backwards compatibility mantra for so long that it is impossible for them to move forward. And all the while, they are alienating the very market share they are so afraid to lose.

 

 

[0] I've released 2 applications on the Market, Telnet and Klaxon, so I feel I have a decent grasp of developing for the Android platform. Klaxon has really helped underscore the huge differences in the platform.

[1] Yes, I realize that IL is not interpreted on the Windows Platform, it is JIT compiled.

[2] As "evil" as Microsoft may be connoted to be, you don't see them on the news exercising their patent rights. Unlike Sun.

[3] I'm thinking about looking into Ruby.

[4] Maybe Google will implement this in the future.

Day 8: VARIANT_BOOL, BOOL, bool, HRESULTs, and managed Exceptions

God, what a mess.

  true false
VARIANT_BOOL -1 0
bool (C#/C++) true false
BOOL (C++) not 0 0
HRESULT >= 0 < 0

I ran into this mess while creating COM interfaces in C# that were being used in C++ (via tlbexp). I discovered some silly behavior with regards to how C# or tlbexp marshals bool return types, which was the cause of a couple bugs:

C# COM Interface:

[Guid("91B57DDB-5CCF-4cb5-9A26-A7F9559BAFFF")]
public interface IFoo
{
    // by default bool is marshalled as VARIANT_BOOL
    bool Bar();
    void Goo();
}

Seriously? Why is it defaulted to VARIANT_BOOL and not BOOL? VARIANT_BOOL is a Visual Basic concept (and a retarded one at that). Looking at the table above, it is the complete opposite behavior of COM HRESULTs. The fix:

[Guid("91B57DDB-5CCF-4cb5-9A26-A7F9559BAFFF")]
public interface IFoo
{
    [return: MarshalAs(UnmanagedType.Bool)]
    bool Bar();
    void Goo();
}

Another issue that bothered me was that these COM calls actually look like the following:

virtual HRESULT __stdcall raw_Bar (
  /*[out,retval]*/long* pRetVal ) = 0;

virtual HRESULT __stdcall Goo () = 0;

All COM calls are returning HRESULTs behind the scenes, which is expected. However, what happens when the C# code throws an exception? You would expect the marshaller to maybe catch it and return an HRESULT failure? Nope. On .NET CF (and maybe even in the desktop version too), the application crashes (without any chance for recovery) in native code. Beautiful. This basically requires that your C# COM methods have a try/catch wrap around all operation, as an exception would be fatal. I guess I can understand why you wouldn't want to have the COM interop handling arbitrarily catch all exceptions, but it is quite tedious to have to do it yourself.

Day 7 or 37, who knows: .Net CF and Marshalling ANSI strings in structures

Consider the following code:

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;

namespace SmartDeviceProject5
{
class Program
{
static void Main(string[] args)
{
Foo foo = new Foo();
try
{
SomeMethod(foo); // KABOOM! NotSupportedException
}
catch (Exception e)
{
}
try
{
AnotherMethod("hello"); // KABOOM! NotSupportedException
}
catch (Exception e)
{
}
}

[DllImport("SomeDLL")]
extern static void SomeMethod(Foo foo);

[DllImport("SomeDLL")]
extern static void AnotherMethod([MarshalAs(UnmanagedType.LPStr)] string someString);
}

public struct Foo
{
public string Bar;
public string Borked;
}

}

When attempting to run this program, it will throw an exception upon calling the SomeMethod PInvoke. Attempting to call the "AnotherMethod" function will fail just as well.
This happens because C# automatically marshals all strings in structures as LPTStr (which for some reason is LPStr in Windows Mobile). However, in methods, strings are marshalled as LPWStr. I don't get it. Anyways, .Net Compact Framework does not support marshalling as LPStr in structures or method calls for whatever reason, even though the code to make it happen is all there (as I will show you).
Changing the code by adding the MarshalAs attribute to explicitly Marshal them as LPWStr would make it work:



    [DllImport("SomeDLL")]
extern static void AnotherMethod([MarshalAs(UnmanagedType.LPWStr)] string someString);
}

public struct Foo
{
[MarshalAs(UnmanagedType.LPWStr)]
public string Bar;
[MarshalAs(UnmanagedType.LPWStr)]
public string Borked;
}


Although LPWStr (Unicode) is more or less the standard now, but if you really really want/need to Marshal it as a LPStr, tough cookies, you get a NotSupportedException.
Generally, if you need to marshal a structure with strings, it's highly unlikely that you are going to need to mix LPWStr and LPStr in the same structure. To that end, I wrote a custom MarshalAnsi class that marshals a structure and all its contents; any strings found are marshalled as LPStr:


using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;

namespace System.Runtime.InteropServices
{
    /// <summary>
    /// .NET Compact framework does not support marshalling strings to ascii.
    /// Need to do it manually.
    /// </summary>
    static class MarshalAnsi
    {
        /// <summary>
        /// This Dictionary maintains all the strings allocated by an IntPtr that a structure
        /// was Marshalled to.
        /// </summary>
        static Dictionary<IntPtr, List<IntPtr>> myStringsForObject = new Dictionary<IntPtr,List<IntPtr>>();

        public static IntPtr StructureToPtr(object structure)
        {
            Type type = structure.GetType();
            var fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.GetField | BindingFlags.Public | BindingFlags.NonPublic);
            
            // determine the total size of the structure. Need to special case strings and bools
            int totalSize = 0;
            foreach (FieldInfo field in fieldInfos)
            {
                totalSize += field.FieldType == typeof(string) ? Marshal.SizeOf(typeof(IntPtr)) :
                              field.FieldType == typeof(bool) ? Marshal.SizeOf(typeof(int)) : Marshal.SizeOf(field.FieldType);
            }

            // allocate the pointer, and create it's list of allocated strings
            IntPtr ret = Marshal.AllocHGlobal(totalSize);
            List<IntPtr> strings = new List<IntPtr>();
            myStringsForObject.Add(ret, strings);
            // structure pointer offset, which is incremented as we write to the structure
            int ofs = 0;
            foreach (FieldInfo field in fieldInfos)
            {
                object toWrite = null;

                if (field.FieldType == typeof(string))
                {
                    // allocate memory for the string if need be, and add it to the 
                    // pointers string allocation list
                    string str = field.GetValue(structure) as string;
                    IntPtr strPtr;
                    if (str == null)
                        strPtr = IntPtr.Zero;
                    else
                    {
                        byte[] bytes = Encoding.ASCII.GetBytes(str);
                        strPtr = Marshal.AllocHGlobal(bytes.Length + 2);
                        strings.Add(strPtr);
                        Marshal.Copy(bytes, 0, strPtr, bytes.Length);
                        Marshal.WriteInt16(strPtr, bytes.Length, 0);
                    }
                    toWrite = strPtr;
                }
                else if (field.FieldType == typeof(bool))
                {
                    // need to write this as an int, not a bool. 
                    // BOOL in C/C++ is really an int, which is of size 4.
                    toWrite = (bool)field.GetValue(structure) ? 1 : 0;
                }
                else
                {
                    // just do the default behavior
                    toWrite = field.GetValue(structure);
                }
                Marshal.StructureToPtr(toWrite, (IntPtr)((int)ret + ofs), false);
                // increment the structure pointer offset
                ofs += Marshal.SizeOf(toWrite);
            }

            return ret;
        }

        /// <summary>
        /// Destroy the memory allocated by a structure, and all strings as well.
        /// </summary>
        /// <param name="ptr"></param>
        public static void DestroyStructure(IntPtr ptr)
        {
            List<IntPtr> strings = myStringsForObject[ptr];
            myStringsForObject.Remove(ptr);
            foreach (IntPtr strPtr in strings)
            {
                Marshal.FreeHGlobal(strPtr);
            }
            Marshal.FreeHGlobal(ptr);
        }
    }
}

Usage:
Simply pass a structure into this class and it will return a pointer with the marshalled data. All strings are marshalled as Ansi strings.
Remember to call MarshalAnsi.DestroyStructure with the pointer returned from MarshalAnsi.StructureToPtr when it is no longer in use.

Day 6?: Mergebin - Combine your Unmanaged and Mananaged DLLs into one Handy Package

MC++ is nice. It lets you mix unmanaged and managed code and allows you to easily create assemblies where you need to do a lot of interop work. Unfortunately, MC++ is not available for .NET CF. So, whenever you need to do any significant degree of interop, you usually end up doing one of the following:

  • Doing a lot of PInvokes into code that really isn't PInvoke friendly. This generally results in a lot of manual marshalling of arguments and unsafe code. This doesn't work if what you need to PInvoke is a .lib or a non-flat/C style DLL.
  • Writing a unmanaged DLL that does all the heavy lifting, and creating managed PInvokes to access it.
  • Writing a COM object for Windows Mobile and referencing that in your C# project.

The first solution is pretty kludgy, but it works. The latter two solutions result in two outputs: a managed assembly and an interop DLL. The DLLs must always be deployed with each other to function properly. Not a very elegant solution either.

I've been playing with SQLite recently. SQLite is the most used database engine in the world, and it runs on basically any device imaginable, including Windows Mobile. SQLite is written entirely in C/C++, so naturally someone wrote a managed wrapper for it called System.Data.SQLite.

One of the interesting things I noticed about System.Data.SQLite is that it somehow manages to deploy as one assembly, even though one of the source DLLs is managed and the other is an unmanaged interop. After diving into the managed code, I noticed something quite peculiar: it was calling PInvokes contained within itself! Somehow a single DLL contained both managed and unmanaged code!

Turns out that the creator of SQLite also created a tool called Mergebin that allows you to merge your managed assembly and unmanaged interop assembly into one nice bow tied package. Very elegant! The full source to the Mergebin tool is included with System.Data.SQLite. I looked over it, and although I have a very rough idea of how DLLs work, so the actual technical implementation of it is all Greek to me. Interesting stuff nonetheless!

Note:

Just a few posts ago, I talked about how I managed to combine two .NET assemblies into one. It involved embedding one assembly as a resource of it's dependent assembly. Pretty kludgy. I probably should have Googled to see if there was a tool possible to merge two .NET assemblies, and there is: ILMerge. I haven't looked into it at all though, so I'm not sure if it will work for .NET CF.

Extension Methods

Apparently I completely missed the introduction of the extension methods feature with .NET 3.5/CLR 2.0/C#. It's not doing anything new from the old version of the CLR per se, but it is very handy syntactic sugar. Basically it takes a static method and uses the first argument to fake out a thiscall.

using System;
using System.Runtime.CompilerServices;

namespace ExtensionMethods
{
    public static class ExtensionMethods
    {
        [Extension]
        public static void PrintMe(this string someString)
        {
            Console.WriteLine(someString);
        }
    }
}
using System;

namespace ExtensionMethods
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            string coolString = "hello world";
            coolString.PrintMe();                   // pretty neat!
        }
    }
}

Compile Time Generics in C# and VB... sort of

I've had a major gripe with .NET for a while; a feature that I was addicted to in C++, but is just not feasible in (or implemented, I don't know which) in .NET: Compile Time Generics.

I seem to constantly run into scenarios where I want to templatize a class, but it is not possible for one reason or another. For example, consider this template struct that would work perfectly fine in C++:

namespace TaskTest
{
    unsafe struct Vector<MyVectorType, MyVectorSize>
    {
        public fixed MyVectorType Items[MyVectorSize];

        public static Vector operator+(Vector one, Vector two)
        {
            for (int i = 0; i < MyVectorSize; i++)
            {
                one.Items[i] += two.Items[i];
            }
            return one;
        }
    }
}

This is a very useful struct when doing any low level graphics related development (OpenGL, Direct3D), but it is not available on .NET Framework. (Well, .NET 3.5 on full blown Windows has a Vector3D)

Incidentally, the fixed size array means it's contents are actually a part of the total memory footprint of the structure. I.e., if you were to get a pointer to that structure, the first 4 bytes would be the first element in the array. If it were a regular array, the first 4 bytes would be a pointer to that array object. This is useful because you can pass an array of managed Vectors to OpenGL and all the data is in one contiguous block of memory.

Anyhow, I digress; I needed to templatize this structure into several flavors: Vector4f (4 floats), Vector3f, Vector4i (4 ints), Vector3i, Vector4d... etc, etc. Then imagine doing this again for Matrix3f, Matrix4f... etc.

But this is not possible with .NET generics for a couple reasons:

  1. You can't pass in an int value as a template argument.
  2. You can't constrain the template type MyVectorType to require an operator+ be implemented. You get a compile time error on the line of code that attempts to add the types.

Or consider this classic example:

namespace TaskTest
{
    public partial class FunkyControl<MyControlType> : MyControlType
    {
        bool myHasGottenFocus = false;
        protected override void OnGotFocus(EventArgs e)
        {
            if (myHasGottenFocus)
                return;
            myHasGottenFocus = true;
            MessageBox.Show("Funky!");
        }
    }
}

This class takes any System.Windows.Forms.Control inheriting type and overrides it so when the user first puts focus on it, it pops up a MessageBox. Or it may not even be a System.Windows.Control, it may just be an object that has a virtual OnGotFocus method. However this scenario is not possible either: the generic parameter can not be the base class of the resultant type.

So, my awesome hack of a solution was to create an MSBuild Task that basically looks at a code file and does a copy, paste, search, and replace to generate new code files with your resultant types:

using System;
using System.Collections.Generic;
using System.Text;

// @CompileTimeGeneric Vector4f::MyVectorSize:4;<MyVectorType>:;MyVectorType:float;Vector:Vector4f@
// @CompileTimeGeneric Vector3f::MyVectorSize:3;<MyVectorType>:;MyVectorType:float;Vector:Vector3f@

namespace TaskTest
{
    unsafe struct Vector<MyVectorType>
    {
        public fixed MyVectorType Items[MyVectorSize];

        public static Vector operator+(Vector one, Vector two)
        {
            for (int i = 0; i < MyVectorSize; i++)
            {
                one.Items[i] += two.Items[i];
            }
            return one;
        }
    }
}

Note the comments. The build task locate the files you wish to create from the contents of the input file by searching for a certain regular expression match.

A sample match would be the following:

@CompileTimeGeneric OutputFileWithoutExtension1:Search1:Replace1;Search2:Replace2@

@CompileTimeGeneric OutputFileWithoutExtension2:Search1:Replace1@

The search and replace takes place in the order listed. One input file can generate as many output files as you need. Unfortunately this isn't a full blown implementation of generics like C++: it doesn't support recursive instantiation of generic types (like using the compiler to calculate out the Nth value in the Fibonacci series). But it works well enough for what I need!

Here is the full source for the Tasks.dll and Tasks.Targets.xml. You will need to add the Tasks.Targets.xml file to your project.

<Import Project="..\Tasks.Targets.xml" />

And for all files that you want to generate Compile Time Generics, change the Build action to "CompileTimeGeneric" in the properties window:

CTGThumbnail

That should do it! The task will create temporary files containing the generics in the bin\obj directory and add them to your Compile list.

P.S. Yes, I know this is a complete hack.

P.P.S. No, I am not proud of this code by any means. It's a means to an end; a way to save time without sacrificing performance so I can do development on more interesting stuff.

P.P.P.S. Mmm, template metaprogramming. I miss you.

Sensory Overload

SensoryOverload

A few days ago I published the Managed OpenGL ES wrapper. As a proof of concept, I went so far as to create a simple game for the HTC Touch Diamond that utilizes the G-Sensor, Nav Sensor, and the 3D hardware capabilities of the device. The end result is a simple "Asteroids" type game I call Sensory Overload.

The game is simple:

  • Move the ship by tilting the device.
  • Don't run into an asteroid.
  • Blow up the asteroids into tiny pieces.
  • When an asteroid spawns (it will be faded out), you have 5 seconds to get away from it before it can hurt you.
  • Rotate the Nav sensor clockwise to fire a bullet.
  • Rotate the Nav sensor counter clockwise to fire a spray of bullets. You can only use this special ability once every 5 seconds.
  • Asteroids spawn every 15 seconds.

This is mostly intended as a demo or proof of concept to provide other developers starting ground to create their own amazing games for the HTC Touch Diamond.

Known Bugs:

  • Small asteroids are hard to explode. The bullets travel "through" them between repaints, so they never actually collide. I may fix this in the future.

Click here to download the full source to Sensory Overload.

Click here to download the Sensory Overload CAB file to play the game.

.NET Compact Framework wrapper for OpenGL ES

OpenGL Test

Around a year ago today, I began writing an extensive UI framework for Windows Mobile. It turned out great, however I continually run into the limitations and performance issues of GDI/GDI+ on mobile devices. One of the steps I wanted to take into really improving performance was to utilize the hardware acceleration that we will begin to see in the new wave of Windows Mobile devices; in my case the HTC Touch Diamond.

The first step towards that end is to utilize one of the two 3D APIs available on the Windows Mobile platform. Direct3D Mobile .NET was not a reasonable option: it has limited support and is supposedly being phased out in Windows Mobile 7. In addition, the D3DM implementation on the HTC Touch Diamond is a just a wrapper around OpenGL ES... I find it a little distasteful that than an operating system specific 3D API is actually just a wrapper around a cross platform 3D API, hehe. And on the other hand, OpenGL ES does not have a managed API.

In My Humble Opinion, UI development should generally be in managed code. Although unmanaged code undoubtedly provides superior performance, the developer sacrifices too much of the ease and speed of managed development.

For that reason, I've started work on a managed wrapper for OpenGL ES: I now have a working set of wrappers for OpenGL ES. I won't take all the credit though. Most of the PInvokes were mass imported via the PInvoke Interop Assistant written by Jared Parsons.

The screen shot above is of the sample "Hello World" application written in Managed OpenGL ES. The code download includes the full source for the wrapper and the sample.

For those wanting to learn OpenGL, I highly recommend reading the NeHe OpenGL series. It's the best OpenGL tutorial on the Internet; I've practically had it book marked for 8 years.

Future work will include converting the various OpenGL constants into enums (I.e., GL_TRIANGLES, GL_TEXTURE0, etc) so that arguments are not so loosely typed.

Notes:

  • The sample uses floating point math, so not all devices may support it.
  • If your device does not have an implementation of OpenGL ES (hardware or software), you can get the free software implementation, Vincent 3D. Just drop the libgles_cm.dll into your \Windows directory. Vincent 3D is a fixed point implementation, so it does not support the sample either. I will probably convert the sample to fixed point eventually.

Windows Mobile Bar Code Manager and API

While I was checking out of the grocery store tonight, I realized I had left my "preferred savings" card in my car's glove compartment as usual. Naturally, my train of thought derailed into Windows Mobile development and how I could make my life easier. The answer was simple: why can't I save all my bar codes into a program and have the cashier scan the image from my cell phone? It would save wallet space and be really cool to boot!

After a quick investigation into how bar codes work, I began coding. The end result is the following:

barcode barcodeedit

Above, I have two of my grocery cards entered into my Bar Code manager. In the editor screen, one can enter a bar code number and view it in real time.

The API (BarCode.dll) is simple:

  1. Create a BarCodeSerializer object.
  2. Set the DisplayNumber property to your bar code number you want to process.
  3. Use the IsValid property verify it is a valid 12 digit bar code.
  4. Use the MakeValid property to make a valid 12 digit bar code from an 11 digit number. Some cards only show 11 of the 12 digits. The 12th is used as a "check" digit.
  5. Use the CreateBitmap method to create a bitmap of approximately the desired dimensions.

In a possible future release, I might extend the bar code manager to take a picture with a high resolution camera and import a bar code number. That would be an interesting computer vision problem!

Download the Bar Code Manager and API here.

Another Klaxon Release

As promised, I implemented more bug fixes and features for this release. Download Klaxon here.

  • The light sensor will only turn off your alarm if the phone is face up. This fixes the issue where the alarm gets shut off if the phones if flipped face down to snooze.
  • If the phone is snoozing, a sensor can not be used to turn the alarm off. The off button must be manually pressed. This is a precaution to ensure the phone doesn't get erroneously turned off.
  • The shake off function is implemented differently now: if at any point, the phone is subject to 20 G's of force, it will turn off. Previously, it was using an orientation change count. The G measurement method is much more reliable.
  • As a silent confirmation, the phone will vibrate once if you put it into Snooze mode. It will Vibrate twice if you turned it off.
  • All the sensor actions are configurable: you can now manually configure what you want the alarm to do when you shake it, flip it, or turn on the light.
  • Implemented some of the UI clean up changes. This includes bigger Vista style check boxes and radio buttons.
  • Implemented an About box which gives you information about your Klaxon version and the author.
  • Fixed a bug where the registry entries were not being deleted properly when an alarm was deleted.
  • Fixed a bug where the device would go to sleep after a Snooze and not wake up to alarm the user.
  • Fixed a bug where the Delay setting was not being saved after editing it.

New Klaxon Release

This new version addresses has the following improvements and fixes:

  • Fixed the bug where the alarm would not immediately fire if the device is in "Sleep" mode.
  • Fixed a bug where the screen would not light up when the alarm fired.
  • Introduced a new Audio Delay feature. Klaxon will now try to wake the user using only the back light for the designated time period. If the user does not snooze or turn off the Klaxon, the alarm will then go off.
  • AppToDate support.
  • Implemented the Light Sensor shut off: When the alarm starts, Klaxon samples the ambient light. If the light ever increases beyond a certain range from that ambient light, Klaxon will shut off the alarm automatically.

CeRunAppAtTime, CeSetUserNotificationEx, Connection Manager Process Scheduling and how they are affected by Power States in .NET Compact Framework

After releasing the first version of Klaxon, several users reported that Klaxon was not starting at the designated time if the device was sleeping: often several minutes late, or not at all.

My implementation of process scheduling was using Connection Manager. At first I thought the device going to sleep was disabling all the active connections, so the event would not fire. I switched the implementation to use CeRunAppAtTime, and still encountered the same problem. CeRunAppAtTime is deprecated and there were several blog posts describing the various issues people had with it. I then switched the implementation again; this time to use CeSetUserNotificationEx, which is the new hotness in process scheduling. Still the same issue. I did notice something peculiar however: if I scheduled the event with a System Notification Dialog (like a calendar event), it would work.

In all 3 implementations, Klaxon would launch immediately after the device was turned on. Another oddity was that the Klaxon form loaded was almost instantaneously, when generally it has a 5-6 second when I launch it via the Programs list. This led me to believe that it was actually launched and resident, but the device was then somehow put back into suspension. Turns out I was right. There are a few well hidden forum posts which document this issue.

Basically, if the device is not explicitly set to a "power on" state within a few seconds of going into the "resuming" state, it goes back into a suspended state. So the fix is to call SetSystemPowerState, which looks like the following:

using System;
using WindowsMobile.Utilities;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;

namespace Klaxon
{
    static class Program
    {
        [DllImport("coredll.dll")]
        extern static UInt32 SetSystemPowerState(String pwsSystemState, UInt32 StateFlags, UInt32 Options);
        const UInt32 POWER_STATE_ON = 0x00010000;
        const UInt32 POWER_FORCE = 0x00001000;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [MTAThread]
        static void Main(string[] args)
        {
            SetSystemPowerState(null, POWER_STATE_ON, POWER_FORCE);
            Run(args);
        }

        static void Run(string[] args)
        {
            InteractiveService.Run(args, typeof(AlarmListForm), new ThreadStart(KlaxonService.Run));
        }
    }
}

Note that I am not calling the InteractiveService.Run in the Main method. This is because when Main is called, all types that it references will have their respective assemblies loaded. In my case, this would be System.Windows.Forms, WindowsMobile.Utilities, and a few others. This would add to the "spin up" time and risk the device being put into suspension before SetSystemPowerState is called.

Klaxon: Windows Mobile G-Sensor and Light Sensor Enabled Alarm Clock

klaxon

I mentioned a post ago that I was working on this. Well it's getting close to completion, and wanted to provide people something to give some feedback on. Right now the finishing touches are in the artwork. Beyond the first screen, the buttons and artwork are really ugly!

You can download Klaxon here.

Using Klaxon is pretty straightforward; it's more or less like the standard Clocks and Alarms application.

G-Sensor Instructions:

  • Flip your phone over to snooze.
  • Shake your phone to turn the alarm off.

Not yet implemented:

  • Artwork (I need to create pretty images to use for buttons)
  • Turn off the alarm if the light comes on in the room (using the Light Sensor!)
  • Turn on the phone light for 15 seconds, so you have a chance to turn off the alarm before it goes off.

Playing MP3s and WMAs using the .Net Compact Framework

I've been working on a new project called Klaxon: it's a G-Sensor enabled alarm clock for Windows Mobile phones. One of the features is that it can allow playback of MP3s and WMAs. I initially wrote the application in .NET 3.5 assuming that the new System.Media.SoundPlayer class would support those audio formats. But, they don't! I ended up writing my own class that handles all the Sound related PInvokes:

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;

namespace WindowsMobile.Utilities
{
    public class SoundPlayer : IDisposable
    {
        [DllImport("aygshell.dll")]
        static extern uint SndOpen(string pszSoundFile, ref IntPtr phSound);

        [DllImport("aygshell.dll")]
        static extern uint SndPlayAsync(IntPtr hSound, uint dwFlags);

        [DllImport("aygshell.dll")]
        static extern uint SndClose(IntPtr hSound);

        [DllImport("aygshell.dll")]
        static extern uint SndStop(int SoundScope, IntPtr hSound);

        [DllImport("aygshell.dll")]
        static extern uint SndPlaySync(string pszSoundFile, uint dwFlags);

        const int SND_SCOPE_PROCESS = 0x1;


        string mySoundLocation = string.Empty;

        public string SoundLocation
        {
            get { return mySoundLocation; }
            set { mySoundLocation = value; }
        }

        IntPtr mySound = IntPtr.Zero;
        Thread myThread = null;
        public void PlayLooping()
        {
            myThread = new Thread(() =>
            {
                while (true)
                {
                    SndPlaySync(mySoundLocation, 0);
                }
            }
            );
            myThread.Start();
        }

        public void Play()
        {
            SndOpen(mySoundLocation, ref mySound);
            SndPlayAsync(mySound, 0);
        }

        public void Stop()
        {
            if (myThread != null)
            {
                SndStop(SND_SCOPE_PROCESS, IntPtr.Zero);
                myThread.Abort();
                myThread = null;
            }
            if (mySound != IntPtr.Zero)
            {
                SndStop(SND_SCOPE_PROCESS, IntPtr.Zero);
                SndClose(mySound);
                mySound = IntPtr.Zero;
            }
        }

        #region IDisposable Members

        public void Dispose()
        {
            Stop();
        }

        #endregion
    }
}

It should work just like System.Media.SoundPlayer.

Omnipresence Beta 1

Finally had a free weekend to work on Omnipresence again. I got a good amount of stuff done:

  • Panning and Zooming do not suspend screen refreshes.
  • Panning the screen does not tax your bandwidth as much. Tuned the compression algorithms to handle it intelligently.
  • Fixed a bug that cause the the screen to "jump" if you panned or zoomed repeatedly.
  • Implemented right click. Click and hold to send a right click.
  • Gave click events tactile feedback: they now vibrate your phone for a split second. This feature can be enabled and disabled in the menu.
  • Implemented several compression techniques. The "best" one is used every frame. Still investigating further tuning of loss-less compression.

Upcoming Features:

  • One of the unmentioned features is that Omnipresence can support multiple clients/viewers at the same time. I need to add a status panel that shows all the current clients on the server.
  • Password based authentication.
  • "Observer" mode. Someone who connects with the specified observer password can only view the session, and not interact.
  • The ability to toggle how double clicks are handled: send to server or client zoom. Right now double clicks are never sent to the server, and that is annoying!
  • Improve on the tactile feedback, by supporting more types.
    • Audio Notification (a customizable beep)
    • Visual Cue (a cross hair that appears where you clicked)
  • Have the client retrieve "larger" than screen dimension images to support faster panning when bandwidth is not an issue.
  • Implement client pacing: the client should intelligently pace its frame requests so it is never waiting for a frame. It should always be either decoding or receiving a frame.

You can download the latest Omnipresence Beta here. Instructions on how to install and use Omnipresence can be found in the original preview post.

Omnipresence Preview

Ok, this is a very early release just for people to check it out. I've mostly been playing around with compression algorithms and investigation of VNC at the moment, so the UI hasn't changed much from the original screen shots. There's a lot of little issues I know about, the primary ones being the inability to unlock a locked machine and being able to click/drag. Anyway, feel free to leave feedback.

Installation:

  1. Verify you have .NET 3.5 installed on your computer.
  2. Verify you have .NET CF 3.5 installed on your device.
  3. Unzip the ZIP file into a directory.
  4. Copy the CAB from the ZIP onto your device and install.
  5. Run Omnipresence.exe on your computer. Start the server.
  6. Run Omnipresence from your device. Type in your IP address/host and hit connect.

Simple instructions:

  • Double tap to zoom in and out
  • Use the HTC Diamond Nav Wheel to smoothly zoom in and out.
  • Drag your finger along the screen to pan.
  • Click and hold to send a right click to the remote machine.
  • You can enter full screen via the menu. You can leave full screen by pressing the center rocker/nav key.
  • I recommend downloading GSen to support screen rotation (I removed it from my app, why do it when someone else does it better?)

Have fun!

Note:

This release only has the Windows Mobile Client and the Windows Server.