latest posts

This morning I will be presenting at the Maryland Code Camp with the topic of Developing Once and Deploying to Many, specifically talking to practices and patterns I've found to help create rich mobile applications efficiently over the last 3 years I've been actively developing for the mobile space. WCF, WPF, PCL, MonoDroid, Azure Mobile Services and Windows Phone 8 are to be discussed.

For the Powerpoint 2013 presentation, all of the code going to be mentioned during the session, the SQL, PSD files and external libraries used, click here to download the zip file.

In addition during the session I will be making reference to an app I wrote earlier this year, jcLOG-IT, specifically the Mobile Azure Service and Windows Live Integration elements.

The code block mentioned for Authentication: [csharp] public async Task AttemptLogin(MobileServiceAuthenticationProvider authType) { try { if (authType == MobileServiceAuthenticationProvider.MicrosoftAccount) { if (!String.IsNullOrEmpty(Settings.GetSetting(Settings.SETTINGS_OPTIONS.LiveConnectToken))) { App.CurrentUser = await App.MobileService.LoginAsync(Settings.GetSetting(Settings.SETTINGS_OPTIONS.LiveConnectToken)); } else { var liveIdClient = new LiveAuthClient(Common.Constants.APP_AUTHKEY_LIVECONNECT); while (_session == null) { var result = await liveIdClient.LoginAsync(new[] {"wl.signin"}); if (result.Status != LiveConnectSessionStatus.Connected) { continue; } _session = result.Session; App.CurrentUser = await App.MobileService.LoginAsync(result.Session.AuthenticationToken); Settings.AddSetting(Settings.SETTINGS_OPTIONS.LiveConnectToken, result.Session.AuthenticationToken); } } } Settings.AddSetting(Settings.SETTINGS_OPTIONS.AuthType, authType.ToString()); Settings.AddSetting(Settings.SETTINGS_OPTIONS.IsFirstRun, false.ToString()); return true; } catch (Exception ex) { Settings.AddSetting(Settings.SETTINGS_OPTIONS.LiveConnectToken, String.Empty); return false; } } [/csharp] The Settings class: [csharp] public class Settings { public enum SETTINGS_OPTIONS { IsFirstRun, LiveConnectToken, AuthType, LocalPassword, EnableLocation } public static void CheckSettings() { var settings = IsolatedStorageSettings.ApplicationSettings; if (!settings.Contains(SETTINGS_OPTIONS.IsFirstRun.ToString())) { WriteDefaults(); } } public static void AddSetting(SETTINGS_OPTIONS optionName, object value) { AddSetting(optionName.ToString(), value); } public static void AddSetting(string name, object value) { var settings = IsolatedStorageSettings.ApplicationSettings; if (!settings.Contains(name)) { settings.Add(name, value); } else { settings[name] = value; } settings.Save(); } public static T GetSetting(SETTINGS_OPTIONS optionName) { return GetSetting(optionName.ToString()); } public static T GetSetting(string name) { if (IsolatedStorageSettings.ApplicationSettings.Contains(name)) { if (typeof(T) == typeof(MobileServiceAuthenticationProvider)) { return (T) Enum.Parse(typeof (MobileServiceAuthenticationProvider), IsolatedStorageSettings.ApplicationSettings[name].ToString()); } return (T) Convert.ChangeType(IsolatedStorageSettings.ApplicationSettings[name], typeof (T)); } return default(T); } public static void WriteDefaults() { AddSetting(SETTINGS_OPTIONS.IsFirstRun, false); AddSetting(SETTINGS_OPTIONS.EnableLocation, false); AddSetting(SETTINGS_OPTIONS.LocalPassword, String.Empty); AddSetting(SETTINGS_OPTIONS.LiveConnectToken, String.Empty); AddSetting(SETTINGS_OPTIONS.AuthType, MobileServiceAuthenticationProvider.MicrosoftAccount); } } [/csharp]
Finally had some time to revisit jcBENCH tonight and found a few issues on the new WPF and Windows Phone 8 releases that I didn't find over the weekend. Unfortunately for the Windows Phone 8 platform, there is a delay between publishing and actually hitting the store. So in the next 24-48 hours, please check out the Windows Phone 8 App Store for the release. You can alternatively just download the current release and await for the Store to indicate there is an update. But for those on Windows, please download the updated release here.
After a considerably longer than expected development time, the big new 0.5 release of jcBENCH is finally available. You can download it from here. [caption id="attachment_1510" align="aligncenter" width="300"] jcBENCH WPF 0.5 Release[/caption] With this new release is an all new WPF GUI and a new C++ Library to help facilitate cross-platform development. The idea being, use the same C++ code across all platforms and to just develop a frontend for each. Also new is a built in viewer of the Top 10 Results and the return of the ability to submit results. Some future enhancements down the road:
  1. OpenCL Benchmark, with my restructuring I have to re-code my C# OpenCL code -> C++ OpenCL code and then add support to the app to determine if OpenCL drivers exist
  2. More comprehensive comparing of results, filtering down to similar spec machines, comparing CPUs used, Manufacturer etc
  3. Ability to run the whole test suite at once (ie if you have a 6 CPU, benchmark it with each CPU used
  4. IRIX 6.5 and Windows Phone 8 clients
If you have suggestions/requests, please let me know, I'm definitely interested in hearing what people have to say.
In working on the new version of jcBench, I made a decision to continue having the actual benchmarking code in C++ (ie unmanaged code) to promote cross-platform deployments. With Windows Phone 8 getting native code support and my obsession with Silicon Graphics IRIX machines I think this is the best route. That being said, the frontends for jcBench will still definitely be done in C# whenever possible. This brings me to my next topic, getting your C++ Library code to be available to your C# application whether that is a console app, WPF, Windows 8 etc. Surprisingly there is a lot of information out there on this, but none of the examples worked for me. With some trial and error I got it working and figured it might help someone out there. So in your C++ (or C) source file: [cpp] extern "C" { __declspec( dllexport ) float runIntegerBenchmark(long numObjects, int numThreads); float runIntegerBenchmark(long numObjects, int numThreads) { CPUBenchmark cpuBenchmark = CPUBenchmark(numObjects, numThreads); return cpuBenchmark.runIntegerBenchmark(); } __declspec( dllexport ) float runFloatingPointBenchmark(long numObjects, int numThreads); float runFloatingPointBenchmark(long numObjects, int numThreads) { CPUBenchmark cpuBenchmark = CPUBenchmark(numObjects, numThreads); return cpuBenchmark.runFloatingPointBenchmark(); } } [/cpp] Notice the __declspec( dllexport ) function declaration, this is key to telling your C# (or any other language) that this function is exposed externally in the DLL. Something else to keep in mind is the difference in types between variables in C++ and C#. A long for instance in C++ is an Int32 in the CLR. Something to keep in mind if you get something like this thrown in your C# application:
This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature
Then in your C# code: [csharp] [DllImport("jcBenchCppLib.dll", CallingConvention = CallingConvention.Cdecl)] public static extern float runIntegerBenchmark(Int32 numObjects, int numThreads); [DllImport("jcBenchCppLib.dll", CallingConvention = CallingConvention.Cdecl)] public static extern float runFloatingPointBenchmark(Int32 numObjects, int numThreads); [/csharp] To execute the function, call it like you would a normal function: [csharp] lblInteger.Content = runIntegerBenchmark(100000, 6) + " seconds"; [/csharp]
With this new release I've fixed a bunch of things in Web Service and the main library that powers all of the clients. In addition I'm tracking a bit more information like the platform and benchmark version (thinking more down the road when specific versions are going to change in the logic in the actual algorithm). Also this release marks the first release of the GUI Mac OS X 10.6 (and later) client. [caption id="attachment_848" align="aligncenter" width="565" caption="jcBENCH on Mac OS X"][/caption] You'll need GTK 2.12 or newer and Mono 2.10.8 or newer to run it. Being my first Mac OS X application ever outside of iOS development, I can without a doubt say I cannot stand development on anything Apple. KVC has got to be the most bloated way of doing things I have ever seen. I am so glad I do not have to do native Mac OS X applications for a living. That being said though, I think it turned out pretty well in matching the WPF version.
It's been a very long time since I released something, so without further adieu, I present jcBENCH. It's a floating point CPU benchmark. Down the road I hope to add further tests, this was just something I wrote on the airplane coming back from San Francisco. You'll need to have .NET 4 installed, if you don't have it, click here. Or you can get it from Windows Update. Click here to download the latest version. I'll make an installer in a few days, just unzip it somewhere on your machine and run. Upon running it, the results get automatically uploaded to my server, a results page will be created shortly.
I've diving into WPF the last couple of weeks focusing on the 2D animation elements, but today I started on the 3D aspect.  Easy enough, it's accelerated in Direct 3D so I could probably throw a ton of polygons/textures at it versus the old GDI+ method I'm used to.  I added in 3D support to my new engine I started to write a few weeks ago this morning.  It didn't take much, just had to re-learn the 3D thought process as far as programming is concerned since it had been a while since I had done 3D graphics programming. Ran into a small hickup though when rendering out some 3D Terrain: [caption id="attachment_4017" align="aligncenter" width="300" caption="Very Bland Looking Terrain"][/caption] It was almost as if the texture coordinates from 3ds max didn't carry over to the xaml file. After opening 3ds max 2011 back up, I noticed I hadn't created a UV Map for it, I was simply using the standard 3ds max texture coordinates. Voilla... [caption id="attachment_4018" align="aligncenter" width="300" caption="Better looking Terrain"][/caption] Not bad, but not 2011 good either.  512x512 textures were acceptable 5-6 years ago, but 2048x2048 is the new "standard" from what I gather. Googling around a bit, found a 2048x2048 uncompressed texture, applied it over the terrain... [caption id="attachment_4019" align="aligncenter" width="300" caption="Much better terrain"][/caption] It looks kinda weird with the trees not parallaxing, but the level of detail is much improved.  I still need to add in support for detail texturing, but it's a good base.