sharpoblunto

Silverlight, one step forward, one step sideways

Posted on Jul 11, 2008 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 tarantula.sharpoblunto.com 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. I hope this tip comes in handy for those trying to access third party web services from silverlight beta 2 apps.

Regarding the reconstruction of a site with additional dynamism

Posted on Jun 20, 2008 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).

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

Silverlight redux

Posted on Apr 16, 2008 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.

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.

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

Tomfoolery with Lua

Posted on Feb 23, 2008 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.

why do people split movies into 700mb blocks?

Posted on Jan 19, 2008 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 source for this program is available here

Hasta Luevo.

News Archive