Showing posts with label programming

Nightmare scenarios, universal parables, and debugging

Posted on 7/18/2010 by Glenn

Labels: ramblings programming

Do you ever get the feeling that you are a subject in some sort of roundabout moralistic parable that is designed to encourage humility and patience in others? For me the most probable cause for this mindset is when a seemingly reasonable task becomes unreasonably complicated and that in finding a solution for the said task I have forced to become a more rounded, knowledgeable, and enlightened individual. Often in these cases, the cause of the problems is due to someone else’s laziness which further enforces the feeling that the moral of the story is that in a greater cosmic sense, slacking off will only create more work for others, in some form or another, at some point in the future.

 

Changing tack slightly, I find the worst thing about developing a large piece of software is the nagging feeling that somewhere in the core foundation of your application is a subtle design problem that is going unnoticed (Be it a performance issue, or a platform issue, or simply an incorrect assumption as to what is and isn’t possible) and that at some point in the future it is going to rear its head as a unsolvable problem that is going to render the entire application as a worthless piece of junk. Its more an unfounded nightmare scenario because thinking rationally, I can quite quickly evaluate the probability of this happening as remote. The reason being that up until now I have never experienced such an issue, and in the end every bug I’ve ever had in software was solvable or could be satisfactorily worked around. However, just because something hasn’t happened yet doesn’t mean that it can’t happen.

 

Now to subtly link the two previous ideas together in a thrilling conclusion filled with sage wisdom, I get onto the problem I had today. I was finding that my game engine was taking over 30 seconds to load when using the Visual Studio 2008 debugger. Of course this made debugging an incredibly frustrating exercise in tedium, and because this is a project that I work on haphazardly in my spare time I wasn’t sure it this was a new issue, or if the engine had simply been getting slower and slower and I had just never noticed. This was this as an incarnation of the nightmare scenario, was my game engine just a slow and bloated piece of shit? Well thankfully no (not yet at least anyway). It turns out that having a bunch of break points set (possibly old invalid ones etc…) causes visual studio to hang for an arbitrarily long time until it gets its shit together and actually loads the program for debugging. Why it does this… no idea (though it reeks of slack coding), but the solution turned out to be simple. Click Debug->Clear all breakpoints and voila, the engine loads up in less than a second.

 

The ironic thing is is that in wrapping both the problem and solution for this issue in a pile of worthless prose, I have effectively made it much harder for anyone else who is looking for a simple solution to find it, and hence I am perpetuating the very feelings of frustration I was complaining about earlier. A sobering thought indeed, but for better or worse its written now, what would be the point of deleting it?

0 Comments

Who is getting all teh lolz?

Posted on 4/13/2009 by Glenn

Labels: dotnet programming

As much as man strives to seek out knowledge and try to understand his place in the universe, some questions remain as mysterious and profound as the day when they entered our collective consciousness.


Well today is a momentous day, as it is now possible to answer with certainty, Who is getting all the lolz, and where are the lolz occurring? If you feel underwhelmed by the scope of this achievement, don’t worry, its true significance will dawn upon you in the coming weeks.


lolmap is an application that uses the Google to find and geolocate the sources of the most popular lolz on all of the internets. Use it wisely, because after all internet lolz are serious business.


image[5]

0 Comments

Enter the Automaton

Posted on 4/2/2009 by Glenn

Labels: dotnet programming

If you’re anything like me, you have a compulsive desire to link, network and otherwise connect every electronic apparatus in the house to every other electronic apparatus in order to create a complicated web of interconnected appliances.

The most obvious example of this is the TV-PC connection to allow me to run media center or XBMC from my PC to my TV in the lounge. While this is pretty standard stuff for any self respecting geek, the geographic distance of my PC to my TV (PC’s up stairs, TV is downstairs in the lounge) means I have to run 5 cables (5.1 surround sound is largely to blame for the cablefest) out of my study, down the stairs and across the lounge to the TV and speakers. This is all well and good, and combined with the XBMC iPod app means I can control the Media center via my iPod or the infrared remote without having to go upstairs to my PC.

However I still have to switch the monitor inputs from my usual dual monitor setup to a cloned desktop with one monitor and TV out before I can see anything on the TV downstairs. Up until now I would go upstairs and do this manually if I wanted to play anything on the computer while I was in the lounge… but obviously this will not do and in the word of infomercial protagonists from time immemorial, “There has to be a better way!”

My solution was to code my way out of this conundrum by writing a nice bit of home automation software I call “Automaton”. Its an http server that runs on my main PC and allows me to submit commands to my PC from any mobile device with a web browser (an iPod touch in my case). It uses a plug-in architecture so I can easily add more automation commands in future as I find myself getting progressively lazier.

The first command I implemented does the following, start media center (or XBMC), switch the monitor configuration to TV out, and when media center is closed revert the monitor configuration back to what it was before.

The other commands are to close the currently active application (i.e media center to revert the monitor configuration), and to shut down, or put the computer into standby. This means that as long as my PC is running I can turn on media center, turn it off and turn my PC off from downstairs… now all I need to to is find a way to turn my PC on remotely and I’ll never have to get up again (I should check out some of the iPod Wake on LAN apps for this purpose methinks)


below is a screenshot of it in action, as usual you can find the installer and source code here.


Note: By default the server runs on port 8086 (This can be changed in the configuration file) so to navigate to the server you should go to http://localhost:8086/


image_thumb[7]


Writing extra plug-ins should be fairly self explanatory (if you know c#) if you have a look at the source. but if its not, let me know :) and I’ll try to help you out.

2 Comments

Silverlight 2.0 released to the internets

Posted on 10/25/2008 by Glenn

Labels: silverlight programming

I've just finished work on upgrading my Silverlight based amazon search engine app "Tarantula" to use the final release of Silverlight 2.0. Its taken a year and a half since what was first known as Silverlight 1.1 was released as an alpha (and coincidentally my first blog post here) to this latest release. In that intervening time I've had to upgrade the application 4 times to alpha refresh, beta 1, and beta 2 and finally to the release version.

To be honest, this latest upgrade was probably the simplest, as there were relatively few breaking changes between beta 2 and the final release, owing to the fact that Silverlight had become pretty mature and fully featured by the time the second beta rolled around. If your interested, check out Tarantula here and see the results of my efforts and frustrations :)

0 Comments

Hearing voices

Posted on 8/15/2008 by Glenn

Labels: dotnet programming

A quick post about a fun little app I wrote a few days ago (with potential to cause all sorts of awesome pranks to the unsuspecting). It allows you to remotely send text to the host computer which will then be read out on the speakers using microsoft text to speech. Its essentially just a windows service which runs an http server, to send speech you just need to make an http get request to the server url and enter the text as a query string e.g.

http://localhost:8080?text=hello world

The http server also accepts http POST's and assumes that the contents of the post contains the text to speak. This tool is not only useful for pranks, its easy to integrate it into notification systems i.e. broken build or code check-in notifiers.

You can find the source and binaries for this application here
0 Comments

Silverlight, one step forward, one step sideways

Posted on 7/11/2008 by Glenn

Labels: silverlight programming

I finally got around to updating my silverlight Amazon.com search engine Tarantula to work with silverlight 2 beta 2 (see it in action here). This update included some relatively minor (as opposed to the wholesale changes from 1.1 alpha to 2.0 beta 1) though essential enhancements. Most of the changes that have been made have been in the area of control templates which were a bit lacking in the first beta release. The introduction of the visual state manager is great and allows for smooth transitions from one control state to another, so I could re add the nice button highlight effects present in the original alpha version of tarantula but which I had to remove in the first beta.

However the reason that I took so long to update Tarantula to work with beta 2 is that Microsoft in their wisdom decided to change the format of remoteaccess.xml files which silverlight applications will accept. To cut a long story short this means that the remoteaccess.xml files used by the amazon.com web services and many other web service providers is now incompatible with silverlight beta 2 clients, rendering those services inaccessible.

So to remedy this I had to write a proxy for the amazon.com services that was hosted on an accessible domain. However I could not be bothered writing a wrapper for the Amazon.com web services (like I did for the alpha version of silverlight) So I wrote a general purpose soap proxy component to do the work for me.

It works as an ASP.Net httphandler and maps local proxy endpoints to their real locations elsewhere on the net. To get it working all you need to do is have an ASP.Net website that will operate as the proxy, add a few config elements to the web.config, then point the silverlight client to the proxy address, and it will all just work as if you were communicating with the services hosted on an inaccessible domain.

In addition to the usual web.config changes to add an httphandler (detailed in the instructions bundled with the soapproxy components download) I had to add the following config entry to the apps.junkship.org site to map the proxy end point to the real amazon service endpoint


<soapProxyComponent>
  <endPointMappings>
    <mapping proxyEndPoint="amazon.ashx" remoteEndPoint="http://soap.amazon.com/onca/soap?Service=AWSECommerceService" />
  </endPointMappings> 
</soapProxyComponent>


Then in Tarantula I had to change the service endpoint in the ServiceReferences.ClientConfig to point to the proxy address instead of the real endpoint.


<endpoint address=http://www.sharpoblunto.com/amazon.ashx
    binding="basicHttpBinding" bindingConfiguration="AWSECommerceServiceBinding" 
contract="Tarantula.AmazonWebService.AWSECommerceServicePortType" name="AWSECommerceServicePort" />


In practice it's worked perfectly and I've bundled the component up for download (either binaries or source code) here, hope it comes in handy for those trying to access third party web services from silverlight beta 2 apps.

1 Comments

Regarding the reconstruction of a site with additional dynamism

Posted on 6/20/2008 by Glenn

Labels: dotnet programming

Of late I've done a redesign of the home page for one of my side projects Junkship. While most of the site was simply static content that I migrated from PHP to asp.net on a new hosting environment, I did add a few new spiffy features around the sites image gallery. Because I'm not a fan of the bloated ASP.NET AJAX framework with its update panels and such, I went for a light weight approach to adding Ajax functionality (I would have liked to redo the whole site using the excellent ASP.NET MVC framework but alas my webhost only supports asp.net 2.0 sites).

 

image_thumb[6]

 

All Ajax postbacks are done using the prototype library which provides a simple and clean means to make Ajax requests to the server, at which point the server renders the desired controls and sends back the html, which prototype can then inject into the page DOM to be rendered.

Returning html controls from AJAX postbacks has a few nice advantages over returning raw xml data that has to be parsed and rendered on the client through JavaScript processing. Firstly it reduces the JavaScript processing that has to be done in order to update the page, as all the client has to do is inject the html subtree into the DOM rather than build its own by picking bits from the response xml. The other nice advantage is that the control rendering only needs to be written once on the server side, not duplicated on the JavaScript side.

 

An issue that comes up when designing Ajax enabled pages is the issue of the browsers back button, namely the breaking thereof. For my image gallery I wanted the back button to take you back a step, but not necessarily to the previous page as you can browse between many images on the same page via Ajax calls. To make this possible I tried to write my own solution by injecting anchor tags into the page via JavaScript, which worked.... on firefox and not much else :). I decided that surely someone else must have already written such a framework, but done a better job and made it cross browser, and it turns out I was right. Its called the RSH framework (Really simple history) and it allows you to specify when you would like to create a snapshot of the page that you would like to return to when the user uses the back or forward buttons. You can add as many of these points as you want and there is a callback system which notifies your JavaScript of page back/forward events and allows you to restore the desired page state based on the snapshot data. It works really well in practice (though I couldn't get it to work on Safari which isn't great because I use safari a lot now on my ipod touch) and means that the page behaves as you would expect.

 

You can view the gallery (and my awesome artwork :)) here

0 Comments

Silverlight redux

Posted on 4/16/2008 by Glenn

Labels: silverlight programming

After my earlier experiments with the alpha releases of Silverlight 1.1 I was extremely keen to give the newly released Silverlight 2.0 Beta 1 a run for its money and port my Tarantula silverlight application from Silverlight 1.1 to silverlight 2.0.

 

 image[9]

 

Now This was easier said than done, not because silverlight 2.0 is difficult to work with (compared to the alphas its a breeze) but because pretty much everything has changed.

 

The addition of user controls (no need to create custom text boxes anymore!) has meant that the xaml markup is a lot closer to what you'd find in WPF, with grid and stackpanel layouts, control styles, and control templates. This means that you can now separate style from structure in the xaml much more effectively and apply consistent styling to user controls. Unfortunately there is a lack of events that control templates expose, for example on mouse exit is not exposed for button templates meaning that fade out effects on buttons are not possible without custom code/markup.

 

Whereas before silverlight app's were deployed as a collection of DLL's and xaml files, they are now deployed into a .xap package, which is just a zip file containing the DLLs, but its a lot tidier and shrinks the download size for silverlight app's.

 

Web service support has drastically improved since the alpha releases. In 1.1 cross domain http requests were not allowed meaning that in order to create a silverlight mashup utilizing external web services you had to actually implement a server side web service proxy to the external services. This was a huge hassle and has thankfully been done away with in 2.0 as you can now make cross domain requests provided that your domain is permitted by their cross domain policy file. Another annoyance in 1.1 was that only JSON web services could be consumed. this has been changed and now it is possible to consume WCF and standard SOAP web services.

 

 image[14]

 

The result of all these changes was that I had to pretty much rewrite all my xaml, and the back end web service code. However thanks to the wonders of the Model View Presenter (MVP) pattern, In particular the Passive View variation of MVP I didn't need to change any of my application logic. The other great thing about the Passive view pattern is that because the View can easily be implemented as mock objects (using Inversion of control and dependency injection) the controllers can be completely unit testable (though I was to lazy to implement any tests :)).

 

The final result is that my application is functionally identical to the original application, though it was much easier to get it all up and running this time than it was the first time, Silverlight is progressing nicely and I am looking forward to the next release. You can find my application here and source code is available for download here

0 Comments

Tomfoolery with Lua

Posted on 2/23/2008 by Glenn

Labels: cplusplus lua programming

I done a fair but of hacking around with the lua scripting language in the past, and while my motives for doing so were oftentimes questionable the fact remains that I learnt a few tricks that make embedding and using it easier.

As a language lua takes a "less is better" approach and instead provides the tools for you to extend its functionality rather than bloating the core distribution with stuff that isn't really necessary. As such you'll need to add some of that bloat yourself :) Henceforth I will be making the dubious assumption that you are familiar with the basics of embedding lua with c++ applications and get right into the meat of things.

Getting a lua stack trace

when a lua script encounters an error you can get the error message from the top of the lua stack by calling

lua_tostring(luaState,-1);


however wouldn't it be more useful to get a full stack trace to give you more context as to where and why the error occurred? Luckily lua includes a nifty mechanism for hooking into events during script execution and while these can be used for all sorts of extremely cool and powerful things, I'll be showing how you can use these events to build a call stack.

firstly lets create a list of strings (we'll be using it as a stack...),a new lua state and hook up some events to it. The lua _sethook function allows you to hook in a number of events and provide a callback function to call when these events occur. In this case we want to be notified whenever a function is called (LUA_MASKCALL) or whenever a function returns (LUA_MASKRET)


std::list<std::string> _stack;
_state = luaL_newstate();
lua_sethook(_state,&FunctionHook,LUA_MASKCALL | LUA_MASKRET,0);

This should allow us to build up a callstack by pushing information on the last called function onto a stack, then popping the top off the stack every time a function returns, simple eh? now on to the implementation of the callback function

void FunctionHook(lua_State *l, lua_Debug *ar)
{


//fill up the debug structure with information from the lua stack

lua_getinfo(l, "Sln", ar);
//push function calls to the top of the callstack
if (ar->event == LUA_HOOKCALL) {

std::stringstream ss;
ss << ar->short_src << ":"

<<
ar->linedefined << ": "
<< (
ar->name == NULL ? "[UNKNOWN]" : ar->name)
<<
" (" << ar->namewhat << ")";

_stack.push_front(ss.str());
}

//pop the returned function from the callstack
else if (ar->event ==LUA_HOOKRET) {

if
(_stack.size()>0)
{

_stack.pop_front();
}
}
}

This function gets automatically called whenever a function is called or a function returns. Each time a call event takes place we push some information regarding that function (name, line number etc...) onto our call stack, and every time a function returns we pop it from the call stack.
So when a lua script encounters an error the contents of the _stack variable will contain a full stack trace up until the point of the error, neat eh? (the cryptic "Sln" parameter for the lua_getinfo function specifies what fields of the lua_Debug struct to populate, see the lua reference manual for more information if you're interested)

NOTE: You'll probably only want to enable this stack tracing for debug builds of your applications as there is a performance hit in hooking into these lua VM events.

At some stage in the future I'll blog about my c++ LuaState class which wraps up the process of creating, loading, running, debugging and cleaning up lua scripts in a nice OO fashion but until then enjoy your new-found stack tracery.
1 Comments

why do people split movies into 700mb blocks?

Posted on 1/19/2008 by Glenn

Labels: dotnet programming

For the love of god people, its 2008, I haven't burned a CD in at least 3 years, we all have hundreds of gigabytes of disk space, USB flash drives which hold multiple gigabytes, and high speed wireless LAN connections in our homes... So why is it that people still distribute movies split into 700mb blocks? who actually needs a movie to fit on a CD nowadays?

For me one of the most annoying things in the world is for a great movie to stop halfway through, right when you're immersed in the story and atmosphere, abruptly forcing you back into the mundane drudgeries of reality to get up off the couch, trudge over to the PC, find the second movie file and hit play. Its not that its a huge inconvieniance, its just that with today's storage technology we can quite happily distribute movie files in one multiple gigabyte file, using the 700mb CD storage limit is completely unecessary.

So anyway, whenever I get a movie split into ridiculous 700mb blocks I insist on merging them into one single file, VirtualDub is a great tool for this as it allows you to do a direct stream copy and append the second file to the first without having to re-encode the video or audio streams. This turns a job that can take upwards of an hour down to a few minutes and also means there is no loss of quality in the source material.

However I am a fan of foreign language films which more often than not come with external subtitle files (usually in .srt format) This means that if you want to merge the video files together you have to do the same for the subtitle files. The problem with this is that its a serious amount of work to do it by hand, so to ease my pain (and possibly yours) I wrote a tool which merges .srt subtitle files together. All you have to do is specify the two subtitle files to merge and also specify the first movie file (so the program knows how far to offset the subtitle timings in the second subtitle file by).

The binaries and source for this program are available here

Hasta Luevo.
0 Comments

Mobile torrentry

Posted on 1/14/2008 by Glenn

Labels: j2me programming

After owning a motorola v3x for the better part of a year it finally dawned upon me the other day that it runs Java applications therefore because I know java (well I hadn't written any in over a year, but hey its like learning to ride a bike right?) I could write an application for my phone. Turns out it was pretty easy to do, I just downloaded the Motorola Java ME SDK v6.4 for Motorola OS Products which includes a plugin for the java eclipse 3.2 IDE and I was able to use the software simulator (image below) to debug and test before deploying onto an actual mobile device.

Untitled-1

So with everything set up I needed an idea for an application, my first thought was toward some sort of remote control device for my PC, this idea eventually morphed into a mobile monitor/control for bittorrent downloads. Since my phone is capable of making http requests It would be a matter of writing or finding a server application that my phone could interact with which would in turn control the bittorrent client.

I already have utorrent set up as a service on a dedicated machine, so It was a matter of finding something a way to expose utorrents functionality to the web, luckily for me utorrent has a webUI component that allows you to view and control your torrents via a web page from anywhere in the world. So far, so good, but it gets even better. The webui also has an API which returns data in JSON format.

So with utorrent and the webui all set up (heres a good guide here) all I had to do was write an application which called the utorrent API and boom, remote torrent action on your mobile! Of course it was easier said than done, but on the whole J2ME was pretty easy going and it didn't take long to write the mobile client. The most difficult part was writing a J2ME compatible API for accessing the utorrent webui web services. Below are a few screenshots of the finished application.

Untitled-3 
Untitled-2

If you want to download this application directly to your mobile (CLDC 1.1/MIDP 2.0 compatible device required) enter this url into your mobile http://www.sharpoblunto.com/Resources/Apps/Downloads/utorrent.jad The source and the binary files are also available here and includes source code
0 Comments

c# project dependancy visualization

Posted on 12/16/2007 by Glenn

Labels: dotnet programming

Have you ever wanted a way to quickly visualize the overall architecture of a c# solution in the form of some sort of pretty diagram?

Well I had that thought yesterday, and figured that there must be some free tool out there that can take a solution file or directory and build a graph of all the underlying project files and dependancies. However to my dismay I found that there were no such tools (or they were commercial products or were completely over the top for what I wanted) so I decided to roll my own :)

The end result is an app which builds a graph of all the projects and dependancies in a directory (plus its subdirectories) as well as the relative sizes of those projects. In addition the graph is fully moveable by the mouse and all the nodes and points behave with realistic physics (I reused my Tarantula physics engine developed a while back)

dependancyAnalyzer

The app is written in c# 2.0 and is available in binary or source code form (under the conditions of the MIT license)

Download the source and binaries here

0 Comments

Mapping boost::signals to .net events

Posted on 11/24/2007 by Glenn

Labels: cplusplus programming

A while back I blogged about wrapping native c++ classes inside managed .net classes using c++/cli, and while that blog detailed wrapping up a class with methods and properties I did not go over how to map across boost::signal's to the .net event model.

Below we have a native c++ class which has the ability to copy files and notify listening classes of it's progress in doing so.

Unmanaged Class Interface

class FileCopier
{


public
:
typedef struct
{
long
BytesCount;
long
BytesCopied;
std::string CurrentFile;
}
CopyProgressEvent;

typedef
boost::signal<void (CopyProgressEvent)>

CopyProgressEventHandler;//progress callback signature

/**
add a listener to copy progress events
*/

void
AddCopyProgressListener(
CopyProgressEventHandler::slot_type listener);

private
:
CopyProgressEventHandler _handler;

};

The AddCopyProgressListener class accepts a pointer to a suitable callback function that conforms to the signature void(CopyProgressEvent) and adds that callback to the event handler
which can be used to notify all listeners of the event. All well and good so now to wrap it up in .net goodness using c++/cli. We'll be using the managed wrapper class I wrote in a previous blog entry (here) as the basis for the file copier wrapper.

The full interface for the wrapper class is shown below, in order for this to work we have to duplicate the copyProgressEvent in a managed class and supply our own delegate class and event for managed listeners to subscribe to. The notifyListeners method is what takes an unmanaged copyProgress event, wraps it up in its managed equivalent and passes it off to the event handler

Managed Class Interface
public ref class
ManagedCopyProgressEvent {

public
:
long
BytesCount;
long
BytesCopied;
System::String^ CurrentFile;
};


public ref class
ManagedFileCopier:
ManagedEntityBase<FileCopier>
{

public
:
delegate
void CopyProgressEventHandler(

ManagedCopyProgressEvent^ args);
event
CopyProgressEventHandler^
OnCopyProgress;

ManagedFileCopier();

public private
:
void
NotifyListeners(
CopyProgressEvent args);
};



Okay, so the interface makes sense to any .net classes wanting to subscribe to the copyprogress events, but how are we going to do the behind the scenes routing of the boost::signal event such that notifyListeners gets called at the appropriate times? If we were working with native c++ classes we can happily used boost::bind to turn the notfyListeners member function into a suitable callback for the signals event, however because NotifyListeners is part of a managed class, this approach doesn't work so we have to take a slightly more roundabout approach.

The notifier proxy

This is where the function below comes in. Its purpose is to provide a valid function for boost::bind to use as a callback, but also to keep a reference to our managed class so that NotifyListeners can be called when a boost::signals event is fired (This should hopefully make more sense when we actually hook all these pieces up in the managed classes constructor)

void
NotifyProxy(
gcroot<ManagedFileCopier ^> this_,
CopyProgressEvent args) {

this_->NotifyListeners(args);
}


Putting it all together

The implementation of the constructor is where the notifier proxy gets hooked up to the unmanaged boost signals event. Using boost::bind we use the notifyProxy function and the instance of the managed class to create a callback for the unmanaged boost::signal.
ManagedFileCopier::ManagedFileCopier() :
ManagedEntityBase(new FileCopier(),true) {
NativeEntity->AddCopyProgressListener(

boost::bind(
NotifyProxy,
gcroot<ManagedFileCopier^>(this),

_1)
);
}


The implementation of the NotifyListeners method is pretty straightforward, we create a new instance of a managedCopyProgressEvent then copy the unmanagd attributes over before passing the object as an argument to the .net OnCopyProgress event.

void ManagedFileCopier::NotifyListeners(
CopyProgressEvent args)
{

ManagedCopyProgressEvent^ mArgs =
gcnew
CopyProgressEvent();

mArgs->BytesCopied = args.BytesCopied;
mArgs->BytesCount = args.BytesCount;

OnCopyProgress(mArgs);
}


So there you have it! thats how you can route events from the boost::signals library though to managed .net code. Below is an example of some c# code using the managed class we've written.

ManagedFileCopier fc = new ManagedFileCopier();

fc.OnCopyProgress +=
new ManagedFileCopier.CopyProgressEventHandler(
OnCopyProgress);

void
OnCopyProgress(ManagedCopyProgressEvent args)
{
...
}



UPDATE: you can find the source for this example here
2 Comments

The trip to c++/cli with unexpected results

Posted on 9/16/2007 by Glenn

Labels: cplusplus programming

I recently had reason to want a virtual file system (i.e a wrapper around the physical file system such that various archive files were enumerated as if they were folders for easy navigation and reading of those files) for use in a C# application. Fortunately I had a piece of code which I had already written... except for one small probelm, the entire thing was written in unmanaged c++.

So armed with the meagre knowledge that there was some way to wrap up native assemblies using some manner of managed c++ ( the latest iteration of which is named c++/cli), I headed off into the scary world of .net/native interop to try and save myself a rewrite of all my code.

c++/cli is the only .net language capable of using managed and unmanaged code in a single assembly, so while being extremely powerful its also extremely complicated as you have a superset of both .net and unmanaged c++ features and all the issues with interoping between them all in a single language. To cut the suspense from this tale, I'll say that I was able to wrap up my unmanaged code without (too many) problems, this included mapping across getter/setter methods as properties, boost::signal callbacks as .net delegates and events and managing the memory of my unmanaged objects within thier managed wrappers.

So without further ado, here are a few useful peices of code and patterns that I used to make wrapping unmanaged entities easier.

Pattern the first: mapping strings
While primitive types such as int's and bools can be passed back and forth between managed and unmanaged code with no conversion, c++'s std::string and .net's string classes need to be mapped explicitly.
Mapping to .net strings from c++ is relatively simple and can be accomplished using the code below

std::string nativeStr;
nativeStr = "hello world";
System::String^ ManagedStr =
gcnew
System::String(nativeStr.c_str());

Mapping from c++ back to .NET is a little bit more complicated but can be accomplished with the function below

std::string MarshalString ( System::String^ s)
{

const
char* chars = (const char*)
(
System::Runtime::InteropServices::
Marshal::StringToHGlobalAnsi(s)).ToPointer();
std::string os = chars;

System::Runtime::InteropServices::Marshal::FreeHGlobal(
System::IntPtr((void*)chars));

return
os;
}

Pattern the second, wrapping managed objects
The two classes below provide a simple means to wrap an unmanaged entity within a managed entity. The templated constructor allows you to pass an unmanaged entity to wrap up and whether the managed wrapper is responsible for freeing the memory of the unmanaged entity upon being garbage collected.

/**
adds some useful utility methods to classes that want to
interop between managed and unmanaged code
*/

public ref class
EntityBase {
public private
:
static
std::string MarshalString ( System::String^ s)
{


const
char* chars =
(
const char*)(System::Runtime::InteropServices::
Marshal::StringToHGlobalAnsi(s)).ToPointer();

std::string os = chars;
System::Runtime::InteropServices::Marshal::
FreeHGlobal(System::IntPtr((void*)chars));

return
os;
}
};


/**
provides a means to wrap an unmanaged type inside a managed
entity
*/

template
<typename T> public ref class ManagedEntityBase:
EntityBase
{

public
:
virtual
~ManagedEntityBase()
{

if
(_ownsNativeEntity) {
delete
_nativeEntity;
}
}

public private
://equivalent to internal in c#

property
T *NativeEntity {
T *get()
{

return
_nativeEntity;
}
}


ManagedEntityBase(T *nativeEntity,bool ownsNativeEntity) {
_nativeEntity = nativeEntity;
_ownsNativeEntity = ownsNativeEntity;
}

private
:

T *_nativeEntity;
bool
_ownsNativeEntity;
};
below is an example of how to use these classes

class UnmanagedClass {
public
:
UnmanagedClass(){}
virtual
~UnmanagedClass(){}

int
Foo() {return 1;}
};


public ref class
ManagedClass:
ManagedEntityBase<UnmanagedClass> {
public
:
ManagedClass():
ManagedEntityBase(new UnmanagedClass(),true) {}
virtual
~ManagedClass(){}

int
Foo() { return NativeEntity->Foo(); }
};


Then after referencing the above c++/cli assembly we can access the managed wrapper in c# with the following

ManagedClass mc = new ManagedClass();
int
bar = mc.Foo();

As for mapping boost::signal callbacks to .NET events and delegates, that was a little more tricky and will be the topic of another days post :)

Hasta Luevo.
3 Comments

Regarding silverlight, services and somesuch.

Posted on 7/16/2007 by Glenn

Labels: silverlight programming

After hearing a lot about Microsoft's Silverlight recently (that and the possibility of loot to be had via a Silverlight coding competition at work :)), I decided to try my hand at a bit of Silverlight development. Basically the idea was to try and build a small demo app that showed off some really wacky stuff that isn't really possible (or practical) to implement using existing web based technologies.
I pretty soon settled on the vague idea of interacting with some sort of third party web service in order to test out Silverlight's ability to leverage existing services and visualise them in strange new ways. Once I'd decided on this I pretty quickly decided to do something with Amazon.com's e-commerce API as I had had some previous experience using it. At the same time I was also fooling around with creating a game based around swarm intelligence (and since got bored of before finishing) which had me thinking about cells and networks.
Combining these two thoughts gave me the idea of writing an application which could search over Amazon's catalogue of books and visualise the results as a group of physical nodes. The user would then be able to drill down into the nodes to find books that were similar, where similar nodes would be connected to the original node creating a visual network.
So after coming up with the idea I looked into actually implementing it and to my dismay I found that Silverlight 1.1 was designed only to work with the upcoming Visual studio Orcas, not Visual Studio 2005. However with a bit of jiggery pokery I was able to get it all running fine in Visual Studio 2005 sans the ability to debug (but my programs contain no errors anyway so that was no problem!).


The web service

Silverlight 1.1 has the ability to with asmx web services using JSON, however it (as of the alpha release) allow you to make cross domain web service calls. This meant that in order to query Amazon's services I would have to write a proxy web service sitting on the same domain that forward the requests on to Amazon then send the results back to the Silverlight client. Though this makes accessing 3rd party services more work, it is relatively painless as there is no difference in writing a Silverlight accessible web service from a standard asmx web service apart from tagging the service class with the [ScriptService] attribute.

Rag-doll physics?
Since I was going to create a visual representation of nodes and links, I thought that the whole app would function much better if everything had a physical tactile feel to it and that the nodes would self arrange in to easily viewable formations, and that meant adding... physics. In the end I decided to model the system as a series of particles which repel one another (meaning that they would arrange themselves nicely on screen) and can optionally be connected by springs (for related nodes).
I implemented this physics model using a simplified Verlet integration scheme (sounds very elaborate but its actually quite straightforward - there's a good article on implementing it here). This method used to be quite popular in the games industry for simulating cloth and rag-doll effects and was used in titles such as Hitman: codename 47 before the industry moved toward more advanced techniques such as inverse kinematics and constrained-rigid-body approaches.
A handy thing I found while developing the physics engine was that because Silverlight uses the same CLR as the full .net framework I could write the physics engine as a standard .net 2.0 class library and test it using a simple Winforms client (as I couldn't do any debugging with Silverlight) then when I was happy with it, I could import it straight into my Silverlight solution, and after changing some references from the standard .net assemblies to the silverlight assemblies it ran fine.

Silverlight client
After implementing the web service back-end and the physics model it was time to hook it all up with some Silverlight eye-candy. Due to the fact the I was working with an alpha release, there is very little in the way of user controls available. This means that unfortunately many standard components such as text boxes and buttons have to be made from scratch. In saying this though, Dave Relyea has produced a controls framework (found here) containing many of these standard controls and though I didn't use his framework I did use some elements of his text-box control when developing my own.
While most of the effects found in WPF are present in Silverlight there are still a few omissions which I found to be a bit annoying, in particular the bitmap effects such as blur are not included in Silverlight which meant that I couldn't add in all the effects I had originally planned, hopefully these effects will be added in for the final release.
On the plus side, I was impressed by Silverlight's rendering speed even at this early stage in its development, as I went out of my way to fill the whole screen up with as many shiny gradients and subtle animations as possible (in addition to the physics modelling) and it still ran along at a decent clip and was responsive to user input even on lower spec machines. 

Untitled-3

 
Not just eye candy
In addition to the draggable books and physics already in-place I wanted to try and implement something that would at least hint at the fact the having all this rich client functionality allows developers to create experiences that are not only more attractive, but also more responsive and in some ways fundamentally different to what is possible using traditional web technologies. My attempt at this was to implement some gesture based controls into the application such that if you shook a book that was connected to another book it would break the link between them, this made it much easier to keep books you wanted on screen and delete unwanted items in a way that felt natural given the physical representation of the books on-screen. While I didn't have the opportunity to pursue further gesture based controls, It certainly would have been possible to remove almost all the buttons from the GUI and have an entirely gesture based interface. 

Untitled-1

 
While its very debatable whether my application is useful rather than just fun to play around with, I think it does illustrate the point that Silverlight has a lot of potential to create some very interesting and powerful experiences on the web, and while there are certainly some issues present in the current releases, I can only see it getting better from here.
If you want to check it out my app, I've got a demo here. If you want to take a look at the source code I've got a copy here (updated to run with Silverlight)

8 Comments