<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>Cuppadev</title>
	<atom:link href="http://www.cuppadev.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cuppadev.co.uk</link>
	<description>Cuppalicious coding!</description>
    <pubDate>Tue, 24 Apr 2012 21:14:05 BST</pubDate>
    <lastBuildDate>Tue, 24 Apr 2012 21:14:05 BST</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
	
	<item>
		<title>Postmortem of a Ludumdare 23 Game</title>

		<link>http://www.cuppadev.co.uk/ludumdare-23-postmortem/</link>
		<comments>http://www.cuppadev.co.uk/ludumdare-23-postmortem/#comments</comments>
		<pubDate>Tue, 24 Apr 2012 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">/ludumdare-23-postmortem/index.html</guid>
		<description><![CDATA[<p>Last weekend I decided to take part in <a href='http://www.ludumdare.com/compo/'>Ludumdare 23 Jam</a>. Here is a short postmortem.</p> <p>The theme was &#8220;Tiny World&#8221;. After a little brainstorming and <a href='http://www.youtube.com/watch?v=Tb-gI_pFog0'>inspiration</a> I decided to have a go at making an RTS.</p> <p>After coming up with a basic list of things to do, I started to work on the engine. Since I wanted the minimum of fuss when it came to actually deploying the game, I decided to try out <a href='http://www.haxenme.org/'>NME</a>, a flash-like API written in haXe which describes itself as a &#8220;a free, open-source framework that enables development for iOS, Android,...]]></description>
		<content:encoded><![CDATA[<p>Last weekend I decided to take part in <a href='http://www.ludumdare.com/compo/'>Ludumdare 23 Jam</a>. Here is a short postmortem.</p>

<p>The theme was &#8220;Tiny World&#8221;. After a little brainstorming and <a href='http://www.youtube.com/watch?v=Tb-gI_pFog0'>inspiration</a> I decided to have a go at making an RTS.</p>

<p>After coming up with a basic list of things to do, I started to work on the engine. Since I wanted the minimum of fuss when it came to actually deploying the game, I decided to try out <a href='http://www.haxenme.org/'>NME</a>, a flash-like API written in haXe which describes itself as a &#8220;a free, open-source framework that enables development for iOS, Android, webOS, BlackBerry, Windows, Mac, Linux and Flash Player from a single codebase&#8221; - perfect!</p>

<p>While the &#8220;game&#8221; ended up being a complete unsubmittable disaster, I still found the experience to be quite insightful.</p>
<img alt='TinyConquer' class='alignnone size-thumbnail' src='/wp-content/uploads/2012/04/tinyconquer-th.png' />
<h3 id='what_went_right'>What went right</h3>

<p>After a few hours I managed to get a basic prototype working with a unit and walls. At this stage, the unit merely moved towards the mouse cursor and collided against the walls. Next came unit-unit collision, which turned out to be a bit more complicated since I decided to use arbitrarily sized bounding boxes.</p>

<p>Path finding ended up being the simplest thing to implement. For this I used AStar. While initially I stumbled across a <a href='http://www.policyalmanac.org/games/aStarTutorial.htm'>rather insightful article with illustrations</a>, I eventually turned to a <a href='http://en.wikipedia.org/wiki/A*_search_algorithm'>more helpful article on wikipedia</a> which filled in the gaps.</p>

<p>At the end of the second day, after asking myself &#8220;am I really having fun making this?&#8221;, I decided not to continue. In the end all I really got implemented was a simple map with units that moved around walls.</p>

<h3 id='what_went_wrong'>What went wrong</h3>

<p><strong>Collision detection</strong></p>

<p>It&#8217;s easy to write code to determine if a collision has occured. It&#8217;s another thing to handle what happens after a collision has occured. While I managed to eventually ironed out most of the issues with the tile collision, later on I found there were still problems if the unit entered a tile incorrectly where it could get stuck.</p>

<p>Simulations are hard to debug, especially when you add in movement and collision. Knowing how annoying buggy collision detection is, I really wanted to get this solid and ended up spending far too much time resolving collision and movement issues.</p>
<img alt='TinyConquer' class='alignnone size-thumbnail' src='/wp-content/uploads/2012/04/rotation-bug.png' />
<p><strong>NME wasn&#8217;t that great</strong></p>

<p>One of my biggest problems was with NME. Not only did I find drawing to be CPU intensive, I stumbled across a rather odd bug with rotations in the HTML5 target. As soon as an element was rotated, the transform for both the sprite and its children became incredibly screwed up. This did not occur in any of the other targets tested.</p>

<p>In addition later on while it worked fine in Chrome and Firefox, Safari was a different matter: I encountered tons of scripting errors and even made it crash!</p>

<p>Finally of note is that text drawing didn&#8217;t work properly in the neko target. While I ended up not needing to draw text, it still put a dampner on things.</p>

<p><strong>Loss of motivation</strong></p>

<p>To start off with, while I hyped myself up beforehand I found that when it came to it, I wasn&#8217;t really &#8220;in the zone&#8221;. This made progress much slower than expected. Half-way through, I started to REALLY loose motivation and ended up procrastinating a lot. Coupled with bumping into silly implementation issues, this really killed development. Realy, I underestimated the effort required to implement something like an RTS from scratch.</p>

<p>In the end, While my game made for a nice tech demo with prototype vector graphics, it was distinctly lacking in gameplay.</p>

<h3 id='to_conclude'>To Conclude</h3>

<p>Using something you don&#8217;t know well in a development contest is a recipe for disaster. Having not used NME before, I wasn&#8217;t quite sure how certain things worked so I was constantly looking back and forward through the documentation.</p>

<p>In comparison had I used something like Unity, 99% of the underlying functionality would already have worked leaving me to work more on the gameplay and art elements which are far more important for a game.</p>

<p>When developing a game, getting gameplay in ASAP is a must. Without it, all you are really staring at is a tech demo, not a game.</p>

<p>For something like Ludumdare, simpler is better. While an RTS is conceptually simple, the underlying framework isn&#8217;t. Looking at <a href='http://www.ludumdare.com/compo/ludum-dare-23/?action=preview&amp;uid=7243'>some</a> <a href='http://www.ludumdare.com/compo/ludum-dare-23/?action=preview&amp;uid=10936'>of</a> <a href='http://www.ludumdare.com/compo/ludum-dare-23/?action=preview&amp;uid=1170'>the</a> <a href='http://www.ludumdare.com/compo/ludum-dare-23/?action=preview&amp;uid=12874'>entries</a>, a lot of the better ones are based on simpler gameplay concepts or backed by powerful game engines.</p>

<p>Finally, it&#8217;s worth remembering that most of the time, a good game isn&#8217;t made in a day. In fact, a good game can take years to create. So don&#8217;t treat Ludumdare as a way of making a new cool hit game. It probably isn&#8217;t going to happen.</p>

<p>For reference, I have put up the <a href='https://github.com/jamesu/tinyconquer'>code to the &#8220;game&#8221; up on github</a>.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Using OpenAL on iOS</title>

		<link>http://www.cuppadev.co.uk/openal-on-ios/</link>
		<comments>http://www.cuppadev.co.uk/openal-on-ios/#comments</comments>
		<pubDate>Thu, 05 Apr 2012 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">/openal-on-ios/index.html</guid>
		<description><![CDATA[<p>Recently I have been tackling problems in <a href='http://www.openal.org'>OpenAL</a> code for an iOS app. The trouble with OpenAL is that despite there being a spec, the underlying implementation for this audio API is mostly undefined. What can work for one system can fail miserably in another.</p> <p>In the case of iOS, no sourcecode is provided so the underlying implementation is partly a mystery, though we can infer from the <a href='http://developer.apple.com/library/ios/#documentation/MusicAudio/Conceptual/AudioUnitHostingGuide_iOS/AudioUnitHostingFundamentals/AudioUnitHostingFundamentals.html'>documentation</a> it uses the AudioUnit API.</p> <p>Here are a some best practices i&#8217;ve developed based on experimentation:</p> <h3 id='do_you_really_need_to_use_openal'>Do you really need to use OpenAL?</h3> <p>In some cases OpenAL may...]]></description>
		<content:encoded><![CDATA[<p>Recently I have been tackling problems in <a href='http://www.openal.org'>OpenAL</a> code for an iOS app. The trouble with OpenAL is that despite there being a spec, the underlying implementation for this audio API is mostly undefined. What can work for one system can fail miserably in another.</p>

<p>In the case of iOS, no sourcecode is provided so the underlying implementation is partly a mystery, though we can infer from the <a href='http://developer.apple.com/library/ios/#documentation/MusicAudio/Conceptual/AudioUnitHostingGuide_iOS/AudioUnitHostingFundamentals/AudioUnitHostingFundamentals.html'>documentation</a> it uses the AudioUnit API.</p>

<p>Here are a some best practices i&#8217;ve developed based on experimentation:</p>

<h3 id='do_you_really_need_to_use_openal'>Do you really need to use OpenAL?</h3>

<p>In some cases OpenAL may be overkill. For instance if you are just playing a one-off sound effect when pressing a button, it&#8217;s probably a better idea to use <a href='http://developer.apple.com/library/mac/#documentation/AVFoundation/Reference/AVAudioPlayerClassReference/Reference/Reference.html'>AVAudioPlayer</a>.</p>

<p>If however you are making a fully immersive 3D AAA shooter, you&#8217;re probably a better off using OpenAL. If you are really crazy, for ultimate control you could even try <a href='http://cuppadev.co.uk/openal-sucks-write-your-own-audio-mixer/'>writing your own audio mixer</a>.</p>

<h3 id='never_reuse_the_same_source_twice'>Never re-use the same source twice</h3>

<p>The implementation of OpenAL on iOS 5.x acts rather oddly when it comes to streaming sources. Lets say you make a music manager and decide to allocate a source. You allocate some buffers then queue them for the source. You then re-use this source to play various music tracks.</p>

<p>However a problems arise as soon as the source is re-used. If you simply stop it and de-allocate buffers, when you queue up a new set of buffers for a new music track the OpenAL implementation seems to get confused and only plays the first buffer you allocate.</p>

<p>Attempting to recover the source at this point is impossible. You can stop it, rewind it, throw buffers away&#8230; nothing seems to get it to work properly. Based on this I can only assume you are not meant to use the same source more than once, at least for streaming sources.</p>

<h3 id='dont_allocate_sources_you_dont_need'>Don&#8217;t allocate sources you don&#8217;t need</h3>

<p>Each source you allocate and play in OpenAL will add a mixing unit to the mixer, which will be mixed to produce the final stream. In addition every source you allocate uses memory.</p>

<p>Instead of allocating a bunch of sources, only allocate sources as you need them. From what i&#8217;ve been able to determine, sources aren&#8217;t that expensive to allocate. It might make sense to limit your allocations however, as there seems to be no fixed limit to the amount of sources you can allocate on iOS.</p>

<p>At one point after receiving a general speedup by changing my source allocation, I theorized that perhaps every source you allocate in OpenAL is mixed regardless of whether or not its playing. However basic experimentation seems to indicate there is no major performance issue with merely allocating lots of sources.</p>

<h3 id='cache_your_buffers_to_disk'>Cache your buffers to disk</h3>

<p>If for example you choose to encode your sound effects in something like OGG format to save space, you might notice it takes a noticeable amount of time to decode the audio each time you buffer it, even when using <a href='http://wiki.xiph.org/Tremor'>Tremor</a>. This is no fun to an end-user.</p>

<p>Using an easier to decode codec is one solution, but if you have long sound effects it&#8217;s still going to take time to decode all the samples.</p>

<p>So it makes sense to keep buffers around for sound effects. However if you have too many buffers you will likely bump into low memory alerts, forcing you to purge non-playing buffers. When you need to play your sound effects again, you need to decode them all over again.</p>

<p>One way you can solve this is by storing your decoded buffers temporarily to disk in the temporary folder (<a href='http://www.cocoadev.com/index.pl?NSTemporaryDirectory'>NSTemporaryDirectory</a>). That way when you get a memory alert you can dump your buffers, then whenever you need them again you can quickly re-load them straight from disk.</p>

<h3 id='to_conclude'>To conclude</h3>

<p>Despite implementation-specific bugs, OpenAL is actually quite a nice and simple library for playing both 2d and 3d audio. There are no licensing fees, the specification is open. It&#8217;s available for practically every relevant modern development platform, what more could you want?</p>

<p>Have fun using OpenAL!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Syncing Youtube with Websockets</title>

		<link>http://www.cuppadev.co.uk/syncing-youtube-with-websockets/</link>
		<comments>http://www.cuppadev.co.uk/syncing-youtube-with-websockets/#comments</comments>
		<pubDate>Fri, 09 Mar 2012 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">/syncing-youtube-with-websockets/index.html</guid>
		<description><![CDATA[<p>A while ago i came across <a href='http://www.synchtube.com'>SynchTube</a>, a rather neat service which allows you to synchronise the playback of a Youtube videos (as well as other services).</p> <p>This creates a rather interesting viewing experience: one can discover and collaboratively critique videos they otherwise would never have seen before.</p> <img alt='Synchtube' class='alignnone size-thumbnail' src='/wp-content/uploads/synchtube-ex-th.jpg' /> <p>After playing around with Synchtube, i was curious as to how it worked. It turns out the embeddable youtube plugin allows you to <a href='https://developers.google.com/youtube/js_api_reference'>query and set the time of a playing video</a>. As long as you have some sort of central authority and a...]]></description>
		<content:encoded><![CDATA[<p>A while ago i came across <a href='http://www.synchtube.com'>SynchTube</a>, a rather neat service which allows you to synchronise the playback of a Youtube videos (as well as other services).</p>

<p>This creates a rather interesting viewing experience: one can discover and collaboratively critique videos they otherwise would never have seen before.</p>
<img alt='Synchtube' class='alignnone size-thumbnail' src='/wp-content/uploads/synchtube-ex-th.jpg' />
<p>After playing around with Synchtube, i was curious as to how it worked. It turns out the embeddable youtube plugin allows you to <a href='https://developers.google.com/youtube/js_api_reference'>query and set the time of a playing video</a>. As long as you have some sort of central authority and a realtime messaging service, you can synchronise playback between multiple users.</p>

<p>In the case of Synchtube, it synchronises the video by sending commands over Websockets. For instance, if you <a href='https://gist.github.com/gists/1088084'>play around with the javascript code</a>, you&#8217;ll find simple JSON messages being processed from the server:</p>

<pre><code>Handling add_user with data [&quot;11b85c64&quot;,null,null,null,false,false,0].
Handling num_votes with data {&quot;votes&quot;:0}.
Handling remove_user with data &quot;0282e6d7&quot;.
Sending &lt; with data &quot;=D&quot;.
Handling &lt; with data [&quot;66716fea&quot;,&quot;=d&quot;].
Handling &lt; with data [&quot;55c2f7fa&quot;,&quot;cats and boots and cats and boots and boots and cats and boots and cats&quot;].
Handling add_user with data [&quot;bbabb3dc&quot;,null,null,null,false,false,0].
Handling num_votes with data {&quot;votes&quot;:0}.
Handling remove_user with data &quot;bbabb3dc&quot;.</code></pre>

<h3 id='onto_the_project'>Onto the Project</h3>

<p>Making youtube videos sync over the web sounded like a cool idea for a project, so i decided to make a simple simple synchronised playback system: play a video in one window, and it&#8217;s replicated in another via a simple Websocket protocol.</p>
<img alt='TestTube 1' class='alignnone size-thumbnail' src='/wp-content/uploads/testtube-ex-1-th.jpg' />
<p>Putting together Sinatra, ActiveRecord, and thin-websocket i made an initial prototype using a simple JSON messaging protocol with two key commands: &#8220;video&#8221; to set the video, and &#8220;video_time&#8221; to set the video time:</p>

<pre><code>[client] {&#39;t&#39;: &#39;subscribe&#39;, &#39;channel_id&#39;: 1}
[server] {&#39;t&#39;: &#39;userjoined&#39;, &#39;user&#39;: {id: =&gt; &#39;anon_123&#39;, name: &#39;Anonymous&#39;, anon: true }}
[server] {&#39;t&#39;: &#39;skip&#39;, &#39;count&#39;: 0}
[server] {&#39;t&#39;: &#39;video&#39;, &#39;time&#39;: 0, &#39;force&#39;: true, &#39;url&#39;: &#39;EJ_wXOFQV3M&#39;, &#39;provider&#39;: &#39;youtube&#39;, &#39;title&#39;: &#39;STALLMANQUEST&#39;, &#39;duration&#39; =&gt; 152.953, &#39;playlist&#39; =&gt; false, &#39;position&#39;: 0, &#39;added_by&#39;: &#39;Anonymous&#39;}</code></pre>

<p>A designated leader simply polled the youtube control and sent updates to all the other clients.</p>

<p>Nice enough, but i decided to continue on by adding more functionality: the playlist, video skipping, chat and moderation. All of this functionality ended up being passed around as simple JSON messages through the Websocket connection.</p>

<p>All was going well until i bumped into a design crisis. Originally i wanted users to sign up in order to create and moderate channels, but this solution was becoming more and more undesirable. I wanted to try something different.</p>

<p>So i borrowed an idea from a <a href='http://en.wikipedia.org/wiki/4chan'>certain anonymous image board</a>: make everyone anonymous and use Tripcodes to identify users who want to be identified.</p>

<p>Why? well after using Synchtube for a while, i found the only thing i was interested in was the sharing and discovery of videos, not the excessive point scoring by the community. I also noticed a general hostility to users without user accounts, which to me detracted from the experience of watching cool videos. By making everyone anonymous by default i hoped to emphasise the viewership aspect.</p>

<p>While this required rewriting half the authentication mechanism, it was well worth it. Except for the administration interface i didn&#8217;t have to worry about implementing user account logic.</p>

<p>Another change i made was to use <a href='http://documentcloud.github.com/backbone/'>Backbone.js</a> to help structure the front-end, as well as the administration interface. While this significantly slowed down development, i felt it really helped to keep the back-end service simple and lightweight.</p>

<h3 id='problems_with_websockets'>Problems with WebSockets</h3>

<p>Websockets are undeniably great as they solve a fundamental problem of how to push messages to clients. Unfortunately though they suffer from poor support in web servers. For instance, during development i was able to serve both the front-end and the Websocket communication through a single port, but i found replicating such a configuration in a production environment to be practically impossible.</p>

<p>Using nginx, i was not able to open a web socket through its HTTP 1.1 backend proxy. This led to the rather undesirable solution of having to serve Websockets directly from the app server on a separate port.</p>

<p>Another problem with Websockets is they don&#8217;t seem to work reliably with cookies. So if for example you want to tie a Websocket connection to a logged in user, you need to use another mechanism to authenticate the user such as generating a user token.</p>

<h3 id='usage_of_backbone'>Usage of backbone</h3>

<p>I have to admit, i hated Backbone.js. It always seemed like a rather arbitrary solution for synchronising models between a client and server. A lot of the examples i saw seemed needlessly complicated and abstracted.</p>

<p>Half-way through development i was getting a bit annoyed at using so many views for something as simple as a list of items, so i decided to refactor and use a different design pattern: use a single view and take advantage of element manipulation and event bubbling in JQuery. This greatly simplified my code in many places, for example:</p>

<pre><code>// Instead of this:

var BanListRow = {
  tagName: &#39;div&#39;,
  className: &#39;ban_row&#39;,
  events: {
    &quot;click a.edit&quot;: &quot;edit&quot;
  }
}
BanListRow.initialize = function() {
  this.model.bind(&quot;change&quot;, this.render, this);
}

...

var BanListPanel = {
  tagName: &#39;div&#39;,
  id: &#39;banedit&#39;,
  events: {
    &quot;click a.add_ban&quot;: &#39;createBan&#39;
  }
}
BanListPanel.initialize = function() {
  BanList.bind(&#39;add&#39;, this.addBan, this);
  BanList.bind(&#39;remove&#39;, this.removeBan, this);
  BanList.bind(&#39;reset&#39;, this.addBans, this);

  BanList.fetch();
}
...

// Consolidate everything together like this :

var BanListPanel = {
  tagName: &#39;div&#39;,
  id: &#39;banedit&#39;,
  events: {
    &quot;click a.add_ban&quot;: &#39;createBan&#39;
  }
}
BanListPanel.initialize = function() {
  BanList.bind(&#39;add&#39;, this.addBan, this);
  BanList.bind(&#39;remove&#39;, this.removeBan, this);
  BanList.bind(&#39;reset&#39;, this.addBans, this);
  BanList.bind(&#39;change&#39;, this.updateBan, this);
}</code></pre>

<p>Generally speaking i found it best to keep objects to a minimum and take advantage of event bubbling. After realising this i felt a bit more comfortable with using Backbone.js.</p>

<h3 id='to_conclude'>To conclude</h3>
<a href='/wp-content/uploads/testtube-ex-2.jpg'>
<img alt='TestTube 2' class='alignnone size-thumbnail' src='/wp-content/uploads/testtube-ex-2-th.jpg' />
</a>
<p>In the end TestTube turned into an anonymous synchronised youtube playlist. For those interested, i put up an instance so you can check it out:</p>

<p><a href='http://testtube.cuppadev.co.uk/r/1'>http://testtube.cuppadev.co.uk/r/1</a></p>

<p>In all i felt this was a really cool project. It goes to show if you have an idea, even if someone has already implemented it there is nothing stopping you from having a go at implementing it yourself.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Calling It Quits on RailsCollab</title>

		<link>http://www.cuppadev.co.uk/quits-on-railscollab/</link>
		<comments>http://www.cuppadev.co.uk/quits-on-railscollab/#comments</comments>
		<pubDate>Thu, 16 Feb 2012 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">/quits-on-railscollab/index.html</guid>
		<description><![CDATA[<p>One of my first rails projects was Railscollab. It started off as nothing more than a proof-of-concept port of ActiveCollab to ruby, and ended up being something more feature complete and in some ways better than the original.</p> <p>Unfortunately after nearly 5 years of sporadic development, i&#8217;m permanently calling it quits.</p> <p>Over the years, i&#8217;ve had various people help out with RailsCollab and enquire about it. Even though it took a while, i kept updating it. I&#8217;ve had everything from hate mail to genuine appreciation. It was even instrumental in landing me a job at a cool startup. But really...]]></description>
		<content:encoded><![CDATA[<p>One of my first rails projects was Railscollab. It started off as nothing more than a proof-of-concept port of ActiveCollab to ruby, and ended up being something more feature complete and in some ways better than the original.</p>

<p>Unfortunately after nearly 5 years of sporadic development, i&#8217;m permanently calling it quits.</p>

<p>Over the years, i&#8217;ve had various people help out with RailsCollab and enquire about it. Even though it took a while, i kept updating it. I&#8217;ve had everything from hate mail to genuine appreciation. It was even instrumental in landing me a job at a cool startup. But really i have never felt a longing attachment to it, and so the project has never really taken off into its own entity.</p>

<p>Lets not forget that even in its minimal state, an open source project is costly to maintain. Rails has a major update pretty much every year, causing problems every time the code is updated. And lets face it: you really do need to keep rails up to date in such a project, since thats where peoples interest lies. It&#8217;s a never-ending cycle.</p>

<p>One also has to look at the state of project management apps to realise that RailsCollab really doesn&#8217;t offer anything revolutionary or compelling to the market space. Basecamp-like &#8220;killer&#8221; systems have been cloned to death, so much that i don&#8217;t even find it funny anymore.</p>

<p>Do i really want to maintain a boring project management apps nobody really needs? The answer is of course no.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Help! I Have a Memory Leak</title>

		<link>http://www.cuppadev.co.uk/help-i-have-a-memory-leak/</link>
		<comments>http://www.cuppadev.co.uk/help-i-have-a-memory-leak/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">/help-i-have-a-memory-leak/index.html</guid>
		<description><![CDATA[<p>Recently i had a project which had some of the worst memory leaks in C++ i&#8217;ve ever had to deal with. It had just about every memory leak problem you could think of, all of which could have been solved with a little bit of planning.</p> <p>Using tools such as <a href='http://valgrind.org/'>Valgrind</a> or <a href='http://developer.apple.com/technologies/tools/'>Instruments</a> surely helps, but they can only help you so much.</p> <p>So if you have a nightmarish C++ project with memory leaks, heres a few ways in which you can solve them.</p> <h3 id='stage_1_forgetfulness'>Stage 1: Forgetfulness</h3> <p>We start off with a simple case: when you make...]]></description>
		<content:encoded><![CDATA[<p>Recently i had a project which had some of the worst memory leaks in C++ i&#8217;ve ever had to deal with. It had just about every memory leak problem you could think of, all of which could have been solved with a little bit of planning.</p>

<p>Using tools such as <a href='http://valgrind.org/'>Valgrind</a> or <a href='http://developer.apple.com/technologies/tools/'>Instruments</a> surely helps, but they can only help you so much.</p>

<p>So if you have a nightmarish C++ project with memory leaks, heres a few ways in which you can solve them.</p>

<h3 id='stage_1_forgetfulness'>Stage 1: Forgetfulness</h3>

<p>We start off with a simple case: when you make an object but never delete it. e.g.:</p>
<div class='highlight'><pre><code class='cpp'>  <span class='n'>Object</span> <span class='o'>*</span><span class='n'>foo</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>();</span> <span class='c1'>// foo never deleted</span>
</code></pre>
</div>
<p>Which can be solved by:</p>
<div class='highlight'><pre><code class='cpp'>  <span class='k'>delete</span> <span class='n'>foo</span><span class='p'>;</span> <span class='c1'>// &lt;&lt;&lt; delete the object</span>
</code></pre>
</div>
<h3 id='stage_2_garbage_collection'>Stage 2: Garbage Collection</h3>

<p>Sometimes you have a pointer to an object which is re-assigned at one point, but the old object is never deleted.</p>
<div class='highlight'><pre><code class='cpp'>  <span class='n'>Object</span> <span class='o'>*</span><span class='n'>foo</span><span class='p'>;</span>

  <span class='n'>foo</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>();</span>
  <span class='c1'>// ... later on ...</span>
  <span class='n'>foo</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>();</span>
</code></pre>
</div>
<p>Which can be solved by deleting the object before re-assigning:</p>
<div class='highlight'><pre><code class='cpp'>  <span class='n'>Object</span> <span class='o'>*</span><span class='n'>foo</span><span class='p'>;</span>

  <span class='n'>foo</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>();</span>
  <span class='c1'>// ... later on ...</span>
  <span class='k'>delete</span> <span class='n'>foo</span><span class='p'>;</span> <span class='c1'>// &lt;&lt;&lt; delete the old object</span>
  <span class='n'>foo</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>();</span>
</code></pre>
</div>
<h3 id='stage_3_destructors'>Stage 3: Destructors</h3>

<p>Some people assume if you make a couple of classes like this:</p>
<div class='highlight'><pre><code class='cpp'>  <span class='k'>class</span> <span class='nc'>Foo</span>
  <span class='p'>{</span>
    <span class='n'>Foo</span><span class='p'>();</span>
    <span class='o'>~</span><span class='n'>Foo</span><span class='p'>();</span>
  <span class='p'>};</span>

  <span class='k'>class</span> <span class='nc'>Woo</span> <span class='o'>:</span> <span class='k'>public</span> <span class='n'>Foo</span>
  <span class='p'>{</span>
    <span class='n'>Woo</span><span class='p'>();</span>
    <span class='o'>~</span><span class='n'>Woo</span><span class='p'>();</span>
  <span class='p'>};</span>
</code></pre>
</div>
<p>If you destroy an instance of <tt>Woo</tt> both <tt>~Woo</tt> and <tt>~Foo</tt> will be called. Only it wont: only <tt>~Woo</tt> will be called. Anything you free in <tt>~Foo</tt> will never be freed.</p>

<p>So if you want <tt>~Foo</tt> to be called too, the destructor for <tt>Foo</tt> needs to be virtual, i.e.:</p>
<div class='highlight'><pre><code class='cpp'>  <span class='k'>class</span> <span class='nc'>Foo</span>
  <span class='p'>{</span>
    <span class='n'>Foo</span><span class='p'>();</span>
    <span class='k'>virtual</span> <span class='o'>~</span><span class='n'>Foo</span><span class='p'>();</span> <span class='c1'>// &lt;&lt;&lt;</span>
  <span class='p'>};</span>
</code></pre>
</div>
<h3 id='stage_4_spaghetti'>Stage 4: Spaghetti</h3>

<p>Things start getting complicated when you have objects which can be referenced by multiple objects. For example:</p>
<div class='highlight'><pre><code class='cpp'>  <span class='n'>Object</span> <span class='o'>*</span><span class='n'>foo</span><span class='p'>,</span> <span class='o'>*</span><span class='n'>child1</span><span class='p'>,</span> <span class='o'>*</span><span class='n'>child2</span><span class='p'>;</span>

  <span class='n'>foo</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>();</span>
  <span class='n'>child1</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>();</span>
  <span class='n'>child1</span><span class='o'>-&gt;</span><span class='n'>parent</span> <span class='o'>=</span> <span class='n'>foo</span><span class='p'>;</span>
  <span class='n'>child2</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>(</span><span class='n'>foo</span><span class='p'>);</span>
  <span class='n'>child1</span><span class='o'>-&gt;</span><span class='n'>parent</span> <span class='o'>=</span> <span class='n'>foo</span><span class='p'>;</span>
</code></pre>
</div>
<p>Now when do we delete <tt>foo</tt>? If we make <tt>child1</tt> or <tt>child2</tt> delete it, we&#8217;ll probably get a crash when we delete <tt>foo</tt> twice. If we delete it elsewhere, how do we know <tt>child1</tt> or <tt>child2</tt> aren&#8217;t still using it?</p>

<p>One possible solution is to use a reference counting system like in Objective C, so when we reach 0 we delete the object:</p>
<div class='highlight'><pre><code class='cpp'>  <span class='k'>class</span> <span class='nc'>Object</span>
  <span class='p'>{</span>
    <span class='n'>Object</span><span class='o'>*</span> <span class='n'>retain</span><span class='p'>()</span>
    <span class='p'>{</span>
      <span class='n'>retainCount</span><span class='o'>++</span><span class='p'>;</span> <span class='c1'>// object is being used</span>
      <span class='k'>return</span> <span class='k'>this</span><span class='p'>;</span>
    <span class='p'>}</span>
    <span class='kt'>void</span> <span class='n'>release</span><span class='p'>()</span>
    <span class='p'>{</span>
      <span class='o'>--</span><span class='n'>retainCount</span><span class='p'>;</span> <span class='c1'>// object is no longer being used</span>
      <span class='k'>if</span> <span class='p'>(</span><span class='n'>retainCount</span> <span class='o'>&lt;=</span> <span class='mi'>0</span><span class='p'>)</span>
        <span class='k'>delete</span> <span class='k'>this</span><span class='p'>;</span>
    <span class='p'>}</span>
    
    <span class='k'>virtual</span> <span class='o'>~</span><span class='n'>Object</span><span class='p'>()</span>
    <span class='p'>{</span>
      <span class='k'>if</span> <span class='p'>(</span><span class='n'>parent</span><span class='p'>)</span> <span class='n'>parent</span><span class='o'>-&gt;</span><span class='n'>release</span><span class='p'>();</span>
    <span class='p'>}</span>
    
    <span class='n'>Object</span> <span class='o'>*</span><span class='n'>parent</span><span class='p'>;</span>
  <span class='p'>};</span>

  <span class='c1'>// ...</span>

  <span class='n'>Object</span> <span class='o'>*</span><span class='n'>foo</span><span class='p'>,</span> <span class='o'>*</span><span class='n'>child1</span><span class='p'>,</span> <span class='o'>*</span><span class='n'>child2</span><span class='p'>;</span>

  <span class='n'>foo</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>();</span>
  <span class='n'>child1</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>();</span>
  <span class='n'>child1</span><span class='o'>-&gt;</span><span class='n'>parent</span> <span class='o'>=</span> <span class='n'>foo</span><span class='o'>-&gt;</span><span class='n'>retain</span><span class='p'>();</span> <span class='c1'>// object is being used by child1</span>
  <span class='n'>child2</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>(</span><span class='n'>foo</span><span class='p'>);</span>
  <span class='n'>child1</span><span class='o'>-&gt;</span><span class='n'>parent</span> <span class='o'>=</span> <span class='n'>foo</span><span class='o'>-&gt;</span><span class='n'>retain</span><span class='p'>();</span> <span class='c1'>// object is being used by child2</span>
</code></pre>
</div>
<p>If you want to be more fancy you can make a smart pointer class, e.g.</p>
<div class='highlight'><pre><code class='cpp'>  <span class='c1'>// Modified Object</span>
  
  <span class='k'>class</span> <span class='nc'>Object</span>
  <span class='p'>{</span>
    <span class='n'>Object</span><span class='o'>*</span> <span class='n'>retain</span><span class='p'>()</span>
    <span class='p'>{</span>
      <span class='n'>retainCount</span><span class='o'>++</span><span class='p'>;</span>
      <span class='k'>return</span> <span class='k'>this</span><span class='p'>;</span>
    <span class='p'>}</span>
  
    <span class='kt'>void</span> <span class='n'>release</span><span class='p'>()</span>
    <span class='p'>{</span>
      <span class='o'>--</span><span class='n'>retainCount</span><span class='p'>;</span>
      <span class='k'>if</span> <span class='p'>(</span><span class='n'>retainCount</span> <span class='o'>&lt;=</span> <span class='mi'>0</span><span class='p'>)</span>
        <span class='k'>delete</span> <span class='k'>this</span><span class='p'>;</span>
    <span class='p'>}</span>
  
    <span class='k'>virtual</span> <span class='o'>~</span><span class='n'>Object</span><span class='p'>()</span>
    <span class='p'>{</span>
      <span class='n'>parent</span> <span class='o'>=</span> <span class='nb'>NULL</span><span class='p'>;</span>
    <span class='p'>}</span>
  
    <span class='n'>ObjectReference</span> <span class='n'>parent</span><span class='p'>;</span>
  <span class='p'>};</span>

  <span class='c1'>// The smart pointer</span>

  <span class='k'>class</span> <span class='nc'>ObjectReference</span>
  <span class='p'>{</span>
  <span class='k'>public</span><span class='o'>:</span>
    <span class='c1'>// Constructor</span>
    <span class='n'>ObjectReference</span><span class='p'>()</span>
    <span class='p'>{</span>
      <span class='n'>object</span> <span class='o'>=</span> <span class='nb'>NULL</span><span class='p'>;</span>
    <span class='p'>}</span>
    
    <span class='c1'>// Assignment initializer</span>
    <span class='n'>ObjectReference</span><span class='p'>(</span><span class='k'>const</span> <span class='n'>ObjectReference</span> <span class='o'>&amp;</span><span class='n'>ref</span><span class='p'>)</span>
    <span class='p'>{</span>
      <span class='n'>object</span> <span class='o'>=</span> <span class='n'>ref</span><span class='p'>.</span><span class='n'>object</span> <span class='o'>?</span> <span class='n'>ref</span><span class='p'>.</span><span class='n'>object</span><span class='o'>-&gt;</span><span class='n'>retain</span><span class='p'>()</span> <span class='o'>:</span> <span class='nb'>NULL</span><span class='p'>;</span>
    <span class='p'>}</span>
    
    <span class='c1'>// Assignment operator</span>
    <span class='n'>ObjectReference</span><span class='o'>&amp;</span> <span class='k'>operator</span><span class='o'>=</span><span class='p'>(</span><span class='k'>const</span> <span class='n'>ObjectReference</span> <span class='o'>&amp;</span><span class='n'>ref</span><span class='p'>)</span>
    <span class='p'>{</span>
      <span class='k'>if</span> <span class='p'>(</span><span class='n'>object</span><span class='p'>)</span> <span class='n'>object</span><span class='o'>-&gt;</span><span class='n'>release</span><span class='p'>();</span>
      <span class='n'>object</span> <span class='o'>=</span> <span class='n'>ref</span><span class='p'>.</span><span class='n'>object</span> <span class='o'>?</span> <span class='n'>ref</span><span class='p'>.</span><span class='n'>object</span><span class='o'>-&gt;</span><span class='n'>retain</span><span class='p'>()</span> <span class='o'>:</span> <span class='nb'>NULL</span><span class='p'>;</span>
      <span class='k'>return</span> <span class='o'>*</span><span class='k'>this</span><span class='p'>;</span>
    <span class='p'>}</span>
    
    <span class='c1'>// Pointer operator</span>
    <span class='k'>operator</span> <span class='n'>Object</span><span class='o'>*</span><span class='p'>()</span>        <span class='p'>{</span> <span class='k'>return</span> <span class='n'>object</span><span class='p'>;</span> <span class='p'>}</span>
    
    <span class='n'>Object</span> <span class='o'>*</span><span class='n'>object</span><span class='p'>;</span> <span class='c1'>// reference to Object</span>
  <span class='p'>};</span>
  
  <span class='c1'>// ...</span>
  
  <span class='n'>Object</span> <span class='o'>*</span><span class='n'>foo</span><span class='p'>,</span> <span class='o'>*</span><span class='n'>child1</span><span class='p'>,</span> <span class='o'>*</span><span class='n'>child2</span><span class='p'>;</span>

  <span class='n'>foo</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>();</span>
  <span class='n'>child1</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>();</span>
  <span class='n'>child1</span><span class='o'>-&gt;</span><span class='n'>parent</span> <span class='o'>=</span> <span class='n'>foo</span><span class='p'>;</span> <span class='c1'>// automagically retains foo</span>
  <span class='n'>child2</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>();</span>
  <span class='n'>child1</span><span class='o'>-&gt;</span><span class='n'>parent</span> <span class='o'>=</span> <span class='n'>foo</span><span class='p'>;</span> <span class='c1'>// automagically retains foo</span>
</code></pre>
</div>
<p>Beware however that when you get a circular reference your objects may never be released using this method.</p>

<h3 id='stage_5_runaway_spaghetti'>Stage 5: Runaway Spaghetti</h3>

<p>Even if you have a reference counting system, you might encounter situations where you release or retain objects too much. Typically memory leak tools only tell you where objects were allocated, not who the retain/release culprit is.</p>

<p>One way of solving this is to keep track of where you retain and release objects</p>
<div class='highlight'><pre><code class='cpp'>  <span class='k'>class</span> <span class='nc'>Object</span>
  <span class='p'>{</span>
    <span class='n'>Object</span><span class='o'>*</span> <span class='n'>retain</span><span class='p'>(</span><span class='kt'>char</span> <span class='o'>*</span><span class='n'>file</span><span class='o'>=</span><span class='nb'>NULL</span><span class='p'>,</span> <span class='kt'>int</span> <span class='n'>line</span><span class='o'>=</span><span class='mi'>0</span><span class='p'>,</span> <span class='kt'>char</span> <span class='o'>*</span><span class='n'>owner</span><span class='o'>=</span><span class='nb'>NULL</span><span class='p'>,</span> <span class='kt'>int</span> <span class='n'>addr</span><span class='o'>=</span><span class='mi'>0</span><span class='p'>)</span> <span class='p'>{</span>
       <span class='n'>retainCount</span><span class='o'>++</span><span class='p'>;</span> 
       <span class='k'>if</span> <span class='p'>(</span><span class='n'>owner</span><span class='p'>)</span>
         <span class='n'>printf</span><span class='p'>(</span><span class='s'>&quot;%x: retain (%i) [%s @ %i] OWNER %s[%x]&quot;</span><span class='p'>,</span> <span class='k'>this</span><span class='p'>,</span> <span class='n'>retainCount</span><span class='p'>,</span> <span class='n'>file</span> <span class='o'>?</span> <span class='n'>file</span> <span class='o'>:</span> <span class='s'>&quot;&quot;</span><span class='p'>,</span> <span class='n'>line</span><span class='p'>,</span> <span class='n'>owner</span><span class='p'>,</span> <span class='n'>addr</span><span class='p'>);</span>
       <span class='k'>else</span>
         <span class='n'>printf</span><span class='p'>(</span><span class='s'>&quot;%x: retain (%i) [%s @ %i]&quot;</span><span class='p'>,</span> <span class='k'>this</span><span class='p'>,</span> <span class='n'>retainCount</span><span class='p'>,</span> <span class='n'>file</span> <span class='o'>?</span> <span class='n'>file</span> <span class='o'>:</span> <span class='s'>&quot;&quot;</span><span class='p'>,</span> <span class='n'>line</span><span class='p'>);</span>  
       <span class='k'>return</span> <span class='k'>this</span><span class='p'>;</span>
    <span class='p'>}</span>

    <span class='kt'>void</span> <span class='n'>release</span><span class='p'>(</span><span class='kt'>char</span> <span class='o'>*</span><span class='n'>file</span><span class='o'>=</span><span class='nb'>NULL</span><span class='p'>,</span> <span class='kt'>int</span> <span class='n'>line</span><span class='o'>=</span><span class='mi'>0</span><span class='p'>,</span> <span class='kt'>char</span> <span class='o'>*</span><span class='n'>owner</span> <span class='o'>=</span> <span class='nb'>NULL</span><span class='p'>,</span> <span class='kt'>int</span> <span class='n'>addr</span><span class='o'>=</span><span class='mi'>0</span><span class='p'>)</span> <span class='p'>{</span>
       <span class='o'>--</span><span class='n'>retainCount</span><span class='p'>;</span>
       <span class='k'>if</span> <span class='p'>(</span><span class='n'>owner</span><span class='p'>)</span>
         <span class='n'>printf</span><span class='p'>(</span><span class='s'>&quot;%x: release (%i) [%s @ %i] OWNER %s[%x]&quot;</span><span class='p'>,</span> <span class='k'>this</span><span class='p'>,</span> <span class='n'>retainCount</span><span class='p'>,</span><span class='n'>file</span> <span class='o'>?</span> <span class='n'>file</span> <span class='o'>:</span> <span class='s'>&quot;&quot;</span><span class='p'>,</span> <span class='n'>line</span><span class='p'>,</span> <span class='n'>owner</span><span class='p'>,</span> <span class='n'>addr</span><span class='p'>);</span>
       <span class='k'>else</span>
         <span class='n'>printf</span><span class='p'>(</span><span class='s'>&quot;%x: release (%i) [%s @ %i]&quot;</span><span class='p'>,</span> <span class='k'>this</span><span class='p'>,</span> <span class='n'>retainCount</span><span class='p'>,</span><span class='n'>file</span> <span class='o'>?</span> <span class='n'>file</span> <span class='o'>:</span> <span class='s'>&quot;&quot;</span><span class='p'>,</span> <span class='n'>line</span><span class='p'>);</span>
   
       <span class='k'>if</span> <span class='p'>(</span><span class='n'>retainCount</span> <span class='o'>&lt;=</span> <span class='mi'>0</span><span class='p'>)</span>
         <span class='k'>delete</span> <span class='k'>this</span><span class='p'>;</span>
    <span class='p'>}</span>
    
    <span class='c1'>// ...</span>
  <span class='p'>};</span>

  <span class='c1'>// ...</span>

  <span class='n'>Object</span> <span class='o'>*</span><span class='n'>foo</span><span class='p'>,</span> <span class='o'>*</span><span class='n'>child1</span><span class='p'>,</span> <span class='o'>*</span><span class='n'>child2</span><span class='p'>;</span>

  <span class='n'>foo</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>();</span>
  <span class='n'>child1</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>();</span>
  <span class='n'>child1</span><span class='o'>-&gt;</span><span class='n'>parent</span> <span class='o'>=</span> <span class='n'>foo</span><span class='o'>-&gt;</span><span class='n'>retain</span><span class='p'>(</span><span class='n'>__FILE__</span><span class='p'>,</span> <span class='n'>__LINE__</span><span class='p'>,</span> <span class='s'>&quot;Object&quot;</span><span class='p'>,</span> <span class='n'>child1</span><span class='p'>);</span>
  <span class='n'>child2</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Object</span><span class='p'>(</span><span class='n'>foo</span><span class='p'>);</span>
  <span class='n'>child1</span><span class='o'>-&gt;</span><span class='n'>parent</span> <span class='o'>=</span> <span class='n'>foo</span><span class='o'>-&gt;</span><span class='n'>retain</span><span class='p'>(</span><span class='n'>__FILE__</span><span class='p'>,</span> <span class='n'>__LINE__</span><span class='p'>,</span> <span class='s'>&quot;Object&quot;</span><span class='p'>,</span> <span class='n'>child2</span><span class='p'>);</span>
</code></pre>
</div>
<p>Then you can simply examine your logs and spot the problematic line of code for that extra release or retain.</p>

<h3 id='final_boss'>Final boss</h3>

<p>Of course once you have solved all of your leaks, you might find you bump into the arch nemesis: Memory Corruption. Specifically, this:</p>
<div class='highlight'><pre><code class='cpp'>  <span class='k'>class</span> <span class='nc'>Entity</span>
  <span class='p'>{</span>
  <span class='k'>public</span><span class='o'>:</span>
    <span class='kt'>float</span> <span class='n'>mNextThink</span><span class='p'>;</span>
  
    <span class='n'>Entity</span><span class='p'>();</span>
    <span class='kt'>void</span> <span class='n'>think</span><span class='p'>();</span>
  <span class='p'>};</span>

  <span class='n'>Entity</span><span class='o'>::</span><span class='n'>Entity</span><span class='p'>()</span>
  <span class='p'>{</span>
  
  <span class='p'>}</span>
</code></pre>
</div>
<p>What is wrong with this? Well say we have some code like this&#8230;.</p>
<div class='highlight'><pre><code class='cpp'>  <span class='k'>for</span> <span class='p'>(</span><span class='kt'>int</span> <span class='n'>i</span><span class='o'>=</span><span class='mi'>0</span><span class='p'>;</span> <span class='n'>i</span><span class='o'>&lt;</span><span class='n'>mEntities</span><span class='p'>.</span><span class='n'>size</span><span class='p'>();</span> <span class='n'>i</span><span class='o'>++</span><span class='p'>)</span>
  <span class='p'>{</span>
    <span class='k'>if</span> <span class='p'>(</span><span class='n'>smCurrentTime</span> <span class='o'>&gt;=</span> <span class='n'>mEntities</span><span class='p'>[</span><span class='n'>i</span><span class='p'>]</span><span class='o'>-&gt;</span><span class='n'>mNextThink</span><span class='p'>)</span>
      <span class='n'>mEntities</span><span class='p'>[</span><span class='n'>i</span><span class='p'>]</span><span class='o'>-&gt;</span><span class='n'>think</span><span class='p'>();</span>
  <span class='p'>}</span>
</code></pre>
</div>
<p>Then <tt>think</tt> may never be called, since <tt>mNextThink</tt> is never initialized, so its value will be undefined. It could be 0, it could be -10000. Who knows. The solution is simple:</p>
<div class='highlight'><pre><code class='cpp'>  <span class='n'>Entity</span><span class='o'>::</span><span class='n'>Entity</span><span class='p'>()</span> <span class='o'>:</span>
  <span class='n'>mNextThink</span><span class='p'>(</span><span class='mi'>0</span><span class='p'>)</span> <span class='c1'>// set a default value</span>
  <span class='p'>{</span>
  <span class='p'>}</span>
</code></pre>
</div>
<p>With all of your memory leaks solved, you should now be able to sleep better.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>The Melancholy of Startups</title>

		<link>http://www.cuppadev.co.uk/the-melancholy-of-startups/</link>
		<comments>http://www.cuppadev.co.uk/the-melancholy-of-startups/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">/the-melancholy-of-startups/index.html</guid>
		<description><![CDATA[<p>Once upon a time i started working for a startup which in hindsight turned into one of the worst moments of my development career. While it certainly wasn&#8217;t all bad, it didn&#8217;t live up to expectations.</p> <p>Before all of this, i thought working in a startup was quite a cool concept. Developers at the start have the power to be instrumental in developing the business and its products, so in a way it sounded like the ultimate creative effort. That combined with the potential of &#8220;The big buyout&#8221; was very attractive proposition.</p> <p>Before i joined, i debated the options. Being...]]></description>
		<content:encoded><![CDATA[<p>Once upon a time i started working for a startup which in hindsight turned into one of the worst moments of my development career. While it certainly wasn&#8217;t all bad, it didn&#8217;t live up to expectations.</p>

<p>Before all of this, i thought working in a startup was quite a cool concept. Developers at the start have the power to be instrumental in developing the business and its products, so in a way it sounded like the ultimate creative effort. That combined with the potential of &#8220;The big buyout&#8221; was very attractive proposition.</p>

<p>Before i joined, i debated the options. Being cautious i didn&#8217;t want to go full-blown into the business, so instead i telecommuted as a freelancer with my other existing commitments.<br />In hindsight this was the best decision i ever made.</p>

<p>At first the working environment was great. I was tasked with implementing some rather cool features into the main product, working with fairly interesting people, some of whom were instrumental in improving the product.<br />Although i technically didn&#8217;t have any obligation to work flat out at times, i did so under the guise of making a difference.</p>

<p>As time went on, i ended up visiting their offices. But it was nothing like i had expected: instead of a &#8220;warm buzz&#8221; of a startup i instead found more of an awkward cold silence. Perhaps this was the first warning something wasn&#8217;t quite right.</p>

<p>Around this time i noticed operations were commonly micro-managed and interrupt-driven, which was ok unless you wanted to get anything done. There always seemed to be a crisis that needed resolving, so i was always on edge.</p>

<p>Besides that, all seemed fine until the next major iteration of the product when development focus changed.</p>

<p>The new focus? Crunch on getting the new release out. Ignore everything else you are doing, no excuses. I developed the dreaded &#8220;Tunnel Vision&#8221; and relentlessly worked. After all, if i wasn&#8217;t doing something, what was i there for?</p>

<p>As the focus on features dwindled, my main role gradually turned into the bug fixer, which from what i can tell was another way of saying &#8220;we don&#8217;t appreciate you anymore.&#8221;</p>

<p>The biggest demotivation came as the team decided to completely rewrite the next version using the next big thing. This effectively meant everything i had worked on and worried about for the past year had amounted to nothing.</p>

<p>As the startup grew, <a href='http://gettingreal.37signals.com/ch07_Meetings_Are_Toxic.php'>weekly meetings were introduced</a> as a means to improve communication and determine who was working on what, which besides wasting time constantly reminded me how boring and mundane my work had become.</p>

<p>By this time I was suffering increasingly from stress and burnout from dealing with the startup and other commitments to make things work out.<br />You could probably have measured my productivity by the amount of lolcats and memes i posted into the company chatroom as a means of coping.</p>

<p>Eventually, things got so worse i had to take a break.</p>

<p>Several months later, i had a hard think: did i really want to continue working in this fashion?<br />The answer was no. I decided to leave for good.</p>

<p>Safe to say in the space of 2 years my illusion of startups being cool, fun companies to work with had been shattered.</p>

<p>I will probably never work for a startup ever again.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>You can't pirate a web app</title>

		<link>http://www.cuppadev.co.uk/you-cant-pirate-a-web-app/</link>
		<comments>http://www.cuppadev.co.uk/you-cant-pirate-a-web-app/#comments</comments>
		<pubDate>Sat, 16 Jul 2011 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">/you-cant-pirate-a-web-app/index.html</guid>
		<description><![CDATA[<p>&#8230;or can you?</p> <p>Since the dawn of consumer computing, people have pirated applications. Why should web apps be any different?</p> <p>Ripping off website designs or application concepts is nothing new. Though usually maintaining such a rip-off is costly and requires a significant effort to maintain. Not to mention one is always playing cat and mouse.</p> <p>I&#8217;ve noticed recently the trend towards fat clients. This is where the application is written using an MVC javascript framework (Backbone, Sproutcore, Cappuccino, etc&#8230;) and the application simply uses a JSON API on the server and renders all the views on the client.</p> <p>A great...]]></description>
		<content:encoded><![CDATA[<p>&#8230;or can you?</p>

<p>Since the dawn of consumer computing, people have pirated applications. Why should web apps be any different?</p>

<p>Ripping off website designs or application concepts is nothing new. Though usually maintaining such a rip-off is costly and requires a significant effort to maintain. Not to mention one is always playing cat and mouse.</p>

<p>I&#8217;ve noticed recently the trend towards fat clients. This is where the application is written using an MVC javascript framework (Backbone, Sproutcore, Cappuccino, etc&#8230;) and the application simply uses a JSON API on the server and renders all the views on the client.</p>

<p>A great deal of logic and assets are stored on the client. The server is merely used as a lightweight data storage and control system.</p>

<p>So if you can write a replacement server, it&#8217;s trivial to &#8220;pirate&#8221; a web service.</p>

<h2 id='an_example'>An example</h2>

<p>Let&#8217;s take <a href='http://www.quietwrite.com/'>QuietWrite</a> for example. A rather nice web-based text editor developed by James Yu.</p>

<p>If we simply save the page to disk, most of the core functionality already works!</p>
<a href='http://www.flickr.com/photos/yajamesu/5943698969/' title='pir-start by yajamesu, on Flickr'><img alt='pir-start' height='377' src='http://farm7.static.flickr.com/6025/5943698969_878e775155.jpg' width='500' /></a>
<p>Of course, editing text is not very useful - we need to save it too.</p>
<a href='http://www.flickr.com/photos/yajamesu/5943699113/' title='pir-fin by yajamesu, on Flickr'><img alt='pir-fin' height='407' src='http://farm7.static.flickr.com/6017/5943699113_45381d908a.jpg' width='500' /></a>
<p>To sum it up, within an hour i was able to replicate the backend enough so that i could save documents.</p>

<p>After finishing the working implementation, i was surprised to find out that James supplies the source code to an example app <a href='http://www.jamesyu.org/2011/01/27/cloudedit-a-backbone-js-tutorial-by-example/'>CloudEdit</a> which has a similar API to QuietWrite.</p>

<p>I needn&#8217;t have written all that code!</p>

<p>Given how easy it is to deploy an app nowadays you could potentially rip off an application, stick your own ads on it, and get it running all within a day. You can even get free updates for the front-end straight from the original developer.</p>

<p>Provided this fat client trend continues, I wonder how long it will be till we start seeing &#8220;CD Keys&#8221;, SecuROM, and other elaborate anti-piracy solutions in web applications.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>How to make a great conference</title>

		<link>http://www.cuppadev.co.uk/making-a-great-conference/</link>
		<comments>http://www.cuppadev.co.uk/making-a-great-conference/#comments</comments>
		<pubDate>Wed, 06 Jul 2011 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">/making-a-great-conference/index.html</guid>
		<description><![CDATA[<p>I received a bit of critique for my <a href='http://cuppadev.co.uk/thoughts-on-euruko-2011/'>Review of Euruko 2011</a>. Granted I was a bit more critical of a few things compared to my twitter feed, but well&#8230;</p> <p>But what do people look for in a conference? No idea. So what do I look for in a conference?</p> <h2 id='the_marketing'>The marketing</h2> <p>There&#8217;s nothing worse than hearing about a conference just when its finished. Maybe I forgot about it, or maybe I just don&#8217;t follow the right people on Twitter&#8230;</p> <p>Whatever the case I really wanted to go, but since the marketing failed I missed out!</p> <p><a href='http://lanyrd.com/'>Lanyrd</a>...]]></description>
		<content:encoded><![CDATA[<p>I received a bit of critique for my <a href='http://cuppadev.co.uk/thoughts-on-euruko-2011/'>Review of Euruko 2011</a>. Granted I was a bit more critical of a few things compared to my twitter feed, but well&#8230;</p>

<p>But what do people look for in a conference? No idea. So what do I look for in a conference?</p>

<h2 id='the_marketing'>The marketing</h2>

<p>There&#8217;s nothing worse than hearing about a conference just when its finished. Maybe I forgot about it, or maybe I just don&#8217;t follow the right people on Twitter&#8230;</p>

<p>Whatever the case I really wanted to go, but since the marketing failed I missed out!</p>

<p><a href='http://lanyrd.com/'>Lanyrd</a> solves this problem partially, but not every conference is listed there. I also don&#8217;t check it regularly.</p>

<p>Even when I hear about an event, there are still more problems that can crop up. Quite a few times i&#8217;ve noticed events listed with poor directions. Please, tell me where your event is, otherwise I can&#8217;t get to it!</p>

<h2 id='the_talks'>The talks</h2>

<p>A great talk is made up of several factors, notably&#8230;</p>

<ul>
<li>The speaker</li>

<li>The content</li>

<li>Relevance to the event</li>
</ul>

<p>So I would suggest a great talk has the best speaker, with the best content which is completely related to the event.</p>

<p>Whereas the worst talk is narrated by the worst speaker, with the most boring content, which is completely unrelated to the event.</p>

<p>Personally I think this is where <a href='http://barcamp.org/'>Barcamp-style</a> conferences shine: there are no rules. A talk could literally be about anything. Everything is relevant.</p>

<p>Then again themed conferences are better in that you know what to expect when you get there. If you go to a ruby conference you get Ruby, not PHP. Not to mention the schedule is usually predetermined.</p>

<h2 id='the_venue'>The venue</h2>

<p>A venue can be the breaking point of the event. It needs to be large enough to accommodate the attendees. It also needs a good layout otherwise congestion will form, making everything look too crowded.</p>

<p>Crowds are great, until everyone starts talking and we bump into the nightclub problem: I CAN&#8217;T HEAR WHAT ANYONE IS SAYING.</p>

<p>Besides the specifics of the building, the venue also needs to be in an accessible location. I don&#8217;t want to trek 10 miles to the venue, and if there is no food provided people need somewhere near to go to eat.</p>

<h2 id='afterevents'>After-events</h2>

<p>I think after-events are also a key part of a conference. Without them your post-conference networking opportunities are limited to the people you just happened to bump into at the conference.</p>

<p>Its also a good opportunity for forming a lasting impression of the event in the heads of attendees. If the party last night was awesome, i&#8217;ll probably be thinking of it months down the line when the next conference is on.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Thoughts on Euruko 2011</title>

		<link>http://www.cuppadev.co.uk/thoughts-on-euruko-2011/</link>
		<comments>http://www.cuppadev.co.uk/thoughts-on-euruko-2011/#comments</comments>
		<pubDate>Sun, 12 Jun 2011 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">/thoughts-on-euruko-2011/index.html</guid>
		<description><![CDATA[<a href='http://www.flickr.com/photos/yajamesu/5825708144/' title='Euruko 2011 by yajamesu, on Flickr'><img alt='Euruko 2011' class='alignnone size-thumbnail' height='281' src='http://farm3.static.flickr.com/2744/5825708144_73ee0b80d8.jpg' width='500' /></a> <p>2 weeks ago I attended the Euruko 2011 event in Berlin. In all I would say it was well worth going to, despite a few flaws.</p> <p>The event was hosted in the <a href='http://maps.google.co.uk/maps/place?cid=5477264429335183868&amp;q=kino+international&amp;hl=en&amp;ved=0CB0Q-gswAA&amp;sa=X&amp;ei=fDr1TaCnD4HQjgfQgJVI'>Kino International</a>, a cinema close to the centre of Berlin. So it was quite easy to find. Connectivity was not a problem either, as the best free wifi i&#8217;ve seen in ages was provided.</p> <p>The quality of the talks was extremely varied. For instance, David Calavera&#8217;s &#8220;JRuby hacking guide&#8221; talk drew...]]></description>
		<content:encoded><![CDATA[<a href='http://www.flickr.com/photos/yajamesu/5825708144/' title='Euruko 2011 by yajamesu, on Flickr'><img alt='Euruko 2011' class='alignnone size-thumbnail' height='281' src='http://farm3.static.flickr.com/2744/5825708144_73ee0b80d8.jpg' width='500' /></a>
<p>2 weeks ago I attended the Euruko 2011 event in Berlin. In all I would say it was well worth going to, despite a few flaws.</p>

<p>The event was hosted in the <a href='http://maps.google.co.uk/maps/place?cid=5477264429335183868&amp;q=kino+international&amp;hl=en&amp;ved=0CB0Q-gswAA&amp;sa=X&amp;ei=fDr1TaCnD4HQjgfQgJVI'>Kino International</a>, a cinema close to the centre of Berlin. So it was quite easy to find. Connectivity was not a problem either, as the best free wifi i&#8217;ve seen in ages was provided.</p>

<p>The quality of the talks was extremely varied. For instance, David Calavera&#8217;s &#8220;JRuby hacking guide&#8221; talk drew me into a state of <a href='http://en.wikipedia.org/wiki/Rapid_eye_movement_sleep'>REM sleep</a>. In fact the next time I have insomnia, I shall be sure to seek his assistance.</p>

<p>In contrast to this, Paolo Perrotta&#8217;s &#8220;The Revenge of method_missing()&#8221; was a stroke of <strong>genius</strong>. Great pacing, casual tone. I found the pictures accompanying the code to be quite complimentary and hilarious.</p>

<p>Really, I could divide the main talks in Euruko into one of several categories.</p>

<p><strong>&#8220;Here&#8217;s my code&#8221;</strong></p>

<p>A talk in which the speaker meticulously describes code, a design pattern, or something equally as boring to the outside observer. Quite often the code does not have any relation to what you are doing.</p>

<p><strong>&#8220;The other day&#8230;&#8221;</strong></p>

<p>A talk in which the speaker tells a story with illustrations or code to accompany their points in a way which is easy to remember.</p>

<p><strong>&#8220;Use my product&#8221;</strong></p>

<p>The speaker describes how they solved a problem, creating a product or project in the process.</p>

<p><strong>EDIT</strong>: i would also like to point out that despite my critique of the talks, <strong>overall</strong> i thought the event was great. Things such as the keynotes and the sing-along at the end were fantastic.</p>

<h2 id='enough_of_the_talks'>Enough of the talks&#8230;</h2>

<p>Of course, a conference is more than just watching people talk in front of an impressive cinema screen. During breaks there was an opportunity to cram into the lobby area for a free drink, or to talk to one of the many developers squished against the walls.</p>

<p>Not to say the venue was small, but given the natural tendency of people to congregate in areas near the seating, doorways, and conference room the feeling of being in a small space was inevitable.</p>

<p>Predictably the free drinks and food ran out quite quickly on both days. Rather deviously someone decided to serve sparkling water next to the still water. My taste-buds still haven&#8217;t recovered.</p>

<h2 id='the_afterevents'>The after-events</h2>

<p>On both days there were events afterwards to go to. I have to say, the party at &#8220;Tante Käthe&#8221; was the most difficult thing to find, even with some helpful pointers provided by the organisers and the modern wonders of GPS.</p>

<p>In fact, if I had not bumped into some other attendees I would never have guessed I needed to go down a dark pathway, over a fence, round a corner and down another dark pathway.</p>

<p>Sadly the planned BBQ was cancelled so there was nothing to eat, though free drinks were available. To be honest though, the event itself did not live up to expectations considering you needed the skills of Indiana Jones to find it.</p>

<p>The second day after-event was the <a href='https://github.com/blog/860-github-drinkup-berlin-may-29th'>Github drinkup</a>. Kudos to Github for the free drinks. However I somewhat suspect if the Github guys weren&#8217;t around, this would never have happened.</p>

<p>Still, drinking in a nice easy to locate venue was a great experience.</p>

<p>So really, was it really worth attending Euruko? Yes. It&#8217;s a great magnet for ruby developers and business people, so networking opportunities were plentiful. And there were several inspiring gems in the talks to make it worth it.</p>

<p>Bring on Euruko 2012!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Maintaining sanity with Automated Software Testing </title>

		<link>http://www.cuppadev.co.uk/maintaining-sanity-with-automated-software-testing/</link>
		<comments>http://www.cuppadev.co.uk/maintaining-sanity-with-automated-software-testing/#comments</comments>
		<pubDate>Sat, 15 Jan 2011 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=793</guid>
		<description><![CDATA[<p>Back when i started on the long and windy road of Software Development, nobody ever seemed to talk about Automated Software testing. None of the articles or books i read about mentioned anything about &#8220;Test driven development&#8221; or even &#8220;Unit Testing&#8221;.</p> <p>In fact, the only testing i heard about was getting a load of people to test your software and send feedback.</p> <h3>Before testing...</h3> <p>Quite often i would encounter stupid bugs during development which made no sense, which could in the worst case scenario take weeks to track down and resolve.</p> <p>Why did it take so long? Because typically i...]]></description>
		<content:encoded><![CDATA[<p>Back when i started on the long and windy road of Software Development, nobody ever seemed to talk about Automated Software testing. None of the articles or books i read about mentioned anything about &#8220;Test driven development&#8221; or even &#8220;Unit Testing&#8221;.</p>

<p>In fact, the only testing i heard about was getting a load of people to test your software and send feedback.</p>
<h3>Before testing...</h3>
<p>Quite often i would encounter stupid bugs during development which made no sense, which could in the worst case scenario take weeks to track down and resolve.</p>

<p>Why did it take so long? Because typically i was following this methodology:</p>
<ol>
<li>Step through code in debugger, find problematic line.</li>
<li>Assume everything not related to the said line(s) worked perfectly.</li>
<li>Spend an extortionate amount of time tweaking lines wondering why "impossible" things were happening based on incorrect assumptions.</li>
</ol>
<p>And when i got problems such as heap corruption&#8230; that was not a pretty sight!</p>

<p>Really, the first time i heard about things such as &#8220;Unit Testing&#8221; was back when i started working with &#8220;Ruby on Rails&#8221;. A lot of rails developers seemed to be bragging about using &#8220;Unit Testing&#8221;, &#8220;rspec&#8221;, or even &#8220;Behaviour Driven Development&#8221;.</p>

<p>However my C++ game developer driven background kicked in and i failed to see the usefulness of such testing. I reasoned:</p>
<ul>
<li>"Automated Software testing doesn't work well for games, they need REAL people to test them"</li>
<li>"I'm too busy writing code to make tests for it!"</li>
<li>"If i write code once and it works, i shouldn't need to check it works again"</li>
</ul><h3>The turning point</h3>
<p>Once i started to work with larger teams however, things like this started to happen:</p>
<ul>
<li>Checked in code, works perfectly</li>
<li>Other guy checks in code, unrelated code breaks</li>
<li>Other guy fails to notice everything else broke</li>
</ul>
<p>When working with a large team, you simply cannot count on everyone knowing as much about the code as you. If something they are not working on breaks, nobody notices. That is where Automated Software Testing comes in handy!</p>

<p>It was about this time that i noticed i was growing tired of dealing with countless numbers of regressions and bizarre bugs with my own projects. Sometimes the stupidest mistake when developing would go unnoticed for months.</p>

<p>Then of course after fixing the stupid mistakes, others would crop up - an endless cycle of stamping out fires!</p>

<p>I simply could no longer reasonably dedicate time to haphazardly fixing all these problems, so i caved in and started to take automated software testing more seriously.</p>

<p>Now i can safely say i feel more saner and confident that my code works as it should. I no longer fret about people changing code, since when it is covered by a test they will have to make sure it still works as intended.</p>

<p>So if you want to keep your sanity developing software, be sure to use automated software testing too!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>OpenAL Sucks, Write your own Audio Mixer</title>

		<link>http://www.cuppadev.co.uk/openal-sucks-write-your-own-audio-mixer/</link>
		<comments>http://www.cuppadev.co.uk/openal-sucks-write-your-own-audio-mixer/#comments</comments>
		<pubDate>Sat, 11 Dec 2010 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=772</guid>
		<description><![CDATA[<p>For one of my <a href='http://www.frozensynapse.com'>recent projects</a>, as part of a video recording feature i needed to save mixed audio from OpenAL.</p> <p>The only problem was, you simply cannot do that using any OpenAL implementation i&#8217;ve seen. The only thing which comes remotely close it is the WAV-out device in <a href='http://kcat.strangesoft.net/openal.html'>OpenAL Soft</a>, which for all intensive purposes is useless.</p> <p>So after lots of research, i ended up writing my own audio mixer. But &#8220;how do you write an audio mixer?&#8221; you may ask. It is in fact quite simple, assuming you keep it simple.</p> <img alt='' class='aligncenter size-full wp-image-773'...]]></description>
		<content:encoded><![CDATA[<p>For one of my <a href='http://www.frozensynapse.com'>recent projects</a>, as part of a video recording feature i needed to save mixed audio from OpenAL.</p>

<p>The only problem was, you simply cannot do that using any OpenAL implementation i&#8217;ve seen. The only thing which comes remotely close it is the WAV-out device in <a href='http://kcat.strangesoft.net/openal.html'>OpenAL Soft</a>, which for all intensive purposes is useless.</p>

<p>So after lots of research, i ended up writing my own audio mixer. But &#8220;how do you write an audio mixer?&#8221; you may ask. It is in fact quite simple, assuming you keep it simple.</p>
<img alt='' class='aligncenter size-full wp-image-773' height='137' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/12/sample-mix.png' title='sample-mix' width='265' />
<p>All an audio mixer does is take input samples, multiplies them according to the volume then adds (mixes) them together into an output buffer.</p>

<p>The output buffer typically uses a higher bit-depth than the buffers which are mixed, otherwise there&#8217;s a fair chance for clipping. As a final step the output buffer is converted to the correct sampling rate for output, or in my case recording.</p>
<h3>My Implementation</h3>
<p>For my mixer, i decided upon the following abstraction which handles managing audio channels and buffers</p>
<ul>
<li><strong>SoundMixer</strong> - where all channels are mixed</li>
<li><strong>SoundChannel</strong> - a channel of audio, which links to one or more buffers of audio samples</li>
<li><strong>SoundBuffer</strong> - where the actual audio samples to be mixed are stored</li>
</ul>
<p>The actual mixing takes place in a scratch buffer, which is repeatedly filled then converted and dumped to the target output. The mixing function is as simple as this!</p>
<pre>
<code>
// For each channel....
short* ptr = (short*)in;
float lVol = (channel-&gt;mLeftVolume*mMasterVolume);  // calculate volume
float rVol = (channel-&gt;mRightVolume*mMasterVolume);
for (int i=0; i&lt;size; i++)
{
   int data = *ptr++;
   scratch[i].left  += (data * lVol); // left channel mix
   scratch[i].right += (data * rVol); // right channel mix
}
</code>
</pre>
<p>In the end the whole thing works like this:</p>
<pre>
<code>
short out[44100*2*2]; // output samples (stereo, 16bit pcm, 2 seconds)

SoundMixer *mixer = new SoundMixer(32, 44100); // #channels, sampling rate

SoundChannel *channel = mixer-&gt;allocChannel();
SoundBuffer *buffer = mixer-&gt;allocBuffer();
SoundBuffer *buffer2 = mixer-&gt;allocBuffer();

// Make some buffer data

unsigned short random[11025]; // 1s random data
for (int i=0; i&lt;11025; i++) {
   random[i] = randi(0,65536);
}

unsigned short random2[11025]; // 1s random data
for (int i=0; i&lt;11025; i++) {
   random2[i] = sin((float)i) * (65536/4);
}

// Store data in buffers
// (samples, data, source sampling rate, dest sampling rate, format)
buffer-&gt;buffer(11025, (unsigned char*)random, 11025, 44100, SOFT_MONO16); 
buffer2-&gt;buffer(11025, (unsigned char*)random2, 11025, 44100, SOFT_MONO16);

// Setup channel
channel-&gt;mBuffer = NULL;
channel-&gt;mLeftVolume = 1.0;  // volume is 0-&gt;1.0
channel-&gt;mRightVolume = 1.0;
channel-&gt;mLeftVolume = 100;
channel-&gt;play();             // state is now &quot;playing&quot;

channel-&gt;mBufferQueue.pushBuffer(buffer);  // this will play first
channel-&gt;mBufferQueue.pushBuffer(buffer2); // followed by this

// Actually mix the audio
mixer-&gt;mix(out, 44100/2);       // 0.5 seconds
mixer-&gt;mMasterVolume = 100;
mixer-&gt;mix(out+44100, 44100/2); // +0.5 seconds
mixer-&gt;mix(out+44100, 44100/2); // +0.5 seconds

// Dump
FILE *fp = fopen(&quot;dump.raw&quot;, &quot;w&quot;);
fwrite(out, 1, sizeof(out), fp);
fclose(fp);

// Cleanup
mixer-&gt;freeChannel(channel);
mixer-&gt;freeBuffer(buffer);
delete mixer;
</code>
</pre>
<p>On top of this fancy audio mixer, i basically made my own wrapper for OpenAL. It basically dispatches OpenAL instructions to both the systems OpenAL and my audio mixer.</p>
<pre>
<code>
ALvoid     talBufferData( ALuint   buffer,
                          ALenum   format,
                          ALvoid*  data,
                          ALsizei  size,
                          ALsizei  freq )
{
   sMainBackend-&gt;talBufferData(buffer, format, data, size, freq);
   sSecondBackend-&gt;talBufferData((ALuint)mBufferMap.retreive(buffer), format, data, size, freq);
}
</code>
</pre>
<p>So there you have it, a simple audio mixer which works great when you want to do cool things such as record audio from a game.</p>

<p>In case you dont fancy writing your own audio mixer however, there are plenty of good examples of complete audio mixers scattered about. E.g. <a href='http://kcat.strangesoft.net/openal.html'>OpenAL Soft</a>, <a href='http://www.talula.demon.co.uk/allegro/'>Allegro (addons)</a>.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Encoding Video in Games</title>

		<link>http://www.cuppadev.co.uk/encoding-video-in-games/</link>
		<comments>http://www.cuppadev.co.uk/encoding-video-in-games/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=761</guid>
		<description><![CDATA[<p>A while ago i had a problem in <a href='http://www.frozensynapse.com'>a project i was working on</a>. I needed to record a video of the game and upload it to YouTube, which at first sounds simple but can is in fact quite complex once you factor in everything.</p> <h3>Decisions, Decisions...</h3> <p>One of the most important things to decide upon was how the encoder should function. My criteria was:</p> <ul> <li>It should encode in realtime.</li> <li>It needs to record audio from the gameplay.</li> <li>The resulting video needs to be uploaded to YouTube.</li> </ul> <p>Since I could not afford to block the main thread,...]]></description>
		<content:encoded><![CDATA[<p>A while ago i had a problem in <a href='http://www.frozensynapse.com'>a project i was working on</a>. I needed to record a video of the game and upload it to YouTube, which at first sounds simple but can is in fact quite complex once you factor in everything.</p>
<h3>Decisions, Decisions...</h3>
<p>One of the most important things to decide upon was how the encoder should function. My criteria was:</p>
<ul>
<li>It should encode in realtime.</li>
<li>It needs to record audio from the gameplay.</li>
<li>The resulting video needs to be uploaded to YouTube.</li>
</ul>
<p>Since I could not afford to block the main thread, so i decided upon using a processing thread to encode the frames. For the audio, i ended up writing my own audio mixer as i could not find any suitable audio libraries that could mix to a raw audio buffer. As for YouTube, i decided to use the patent-free <a href='http://www.theora.org'>Ogg Theora</a> codec.</p>
<h3>The specifics</h3>
<p>To handle the actual capture, i made a VideoRecorder object which would periodically extract frames and audio samples, and dispatch them to the encoder thread which was managed by a VideoEncoder. This went through several re-designs until i ended up with something like this:</p>
<img alt='' class='aligncenter size-medium wp-image-762' height='135' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/11/encoder-diag-300x135.png' title='encoder-diag' width='300' />
<p>i.e. the VideoRecorder sends the frames to the VideoEncoder which in turn adds them to the Frame Queue which in turn is processed by the actual Encoder, finally inserting them into the encoded video stream (in this case using Ogg Theora).</p>

<p>I ended up using two queues for video and audio frames, as i needed control over when i could insert video/audio into the encoded stream. In fact, this turned out to be one of the major problems.</p>

<p>In Ogg Theora you need to make sure the video and audio pages you generate are inserted in the correct order in the output stream, otherwise you will get odd playback corruption where frames are dropped, since the decoder will get confused with the timestamps.</p>
<img alt='' class='aligncenter size-medium wp-image-763' height='129' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/11/packet-ex-300x129.png' title='packet-ex' width='300' />
<p>Beyond that, uploading a video to YouTube is remarkably simple. Though to save time, i ended up using the code from Claus Hofele&#8217;s excellent <a href='http://www.gamasutra.com/view/feature/3855/share_your_experience_youtube_.php'>Share Your Experience: YouTube Integration In Games</a> on Gamasutra.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Palettes in ScummC</title>

		<link>http://www.cuppadev.co.uk/palettes-in-scummc/</link>
		<comments>http://www.cuppadev.co.uk/palettes-in-scummc/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=752</guid>
		<description><![CDATA[<p>One thing which i have been meaning to incorporate into <a href='http://github.com/jamesu/scummc'>ScummC</a> for quite a while now is better palette manipulation tools.</p> <img alt='' class='aligncenter size-medium wp-image-753' height='225' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/08/oquest-300x225.png' title='OpenQuest' width='300' /> <p>It seems that sometime after the turn of the century, the art of making an image editor with good palette manipulation seems to have been lost. This is very unfortunate, as it makes it VERY hard to make graphics for scummc.</p> <p>So i improved scummc in two ways&#8230;</p> <h2>The palcat tool is now more useful</h2> <p>Have tons of non-indexed graphics? Well now you can tell palcat to combine...]]></description>
		<content:encoded><![CDATA[<p>One thing which i have been meaning to incorporate into <a href='http://github.com/jamesu/scummc'>ScummC</a> for quite a while now is better palette manipulation tools.</p>
<img alt='' class='aligncenter size-medium wp-image-753' height='225' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/08/oquest-300x225.png' title='OpenQuest' width='300' />
<p>It seems that sometime after the turn of the century, the art of making an image editor with good palette manipulation seems to have been lost. This is very unfortunate, as it makes it VERY hard to make graphics for scummc.</p>

<p>So i improved scummc in two ways&#8230;</p>
<h2>The palcat tool is now more useful</h2>
<p>Have tons of non-indexed graphics? Well now you can tell palcat to combine and quantise all the colours in your images, so you have a single common palette.</p>
<code>palcat -o out -col 32 costume1_*.bmp costume2_*.bmp</code>
<p>Quite commonly in scumm games, you&#8217;ll notice the room palettes will follow the same general schema:</p>
<table>
<tr><th>OFFS</th><th>SIZE</th><th>DESC</th></tr>
<tr><td>0</td><td>16</td><td>System Colors</td></tr>
<tr><td>16</td><td>X</td><td>Room Colors</td></tr>
<tr><td>16+X</td><td>Y</td><td>Costume Colors</td></tr>
</table>
<p>To reproduce with palcat, simply do:</p>
<pre>palcat -o out sys.bmp room.bmp costumes.bmp</pre>
<p>(where costumes.bmp contains your combined costume palette(s))</p>
<h2>The costume compiler helps you</h2>
<p>In scumm, costumes have a palette which indexes into the current room palette. Before you had to specify this manually, like so:</p>
<pre>palette([0-32]);</pre>
<p>Now you can pass in your combined room palette instead, like so:</p>
<pre>palette("out_blank_room.bmp");</pre>
<p>Which will match up colors in out_blank_room.bmp with your costume bitmap.</p>

<p>If you have costumes which will be re-used across rooms, i suggest you make a blank room bitmap so it won&#8217;t accidentally match colors in your room when you don&#8217;t want it to.</p>
<pre>palcat -o out sys.bmp blank_room.bmp actors.bmp</pre>
<p>I&#8217;ve incorporated the costume palette trick in the examples on my scummc fork. Feel free to <a href='http://github.com/jamesu/scummc'>check it out on github</a>!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Where is ScummC?</title>

		<link>http://www.cuppadev.co.uk/where-is-scummc/</link>
		<comments>http://www.cuppadev.co.uk/where-is-scummc/#comments</comments>
		<pubDate>Sat, 17 Jul 2010 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=739</guid>
		<description><![CDATA[<p>With the recent remakes of certain Lucasarts adventure games, i thought to myself &#8220;i wonder how the scummc compiler project is getting on?&#8221;</p> <p>To my shock however, it seems the scummc website suddenly died sometime last year, so nobody was able to check out and learn from the only functioning third party SCUMM compiler.</p> <p>Thankfully i was able to obtain a fairly recent copy of the files in the SVN repository, and coupled with the SVN commit logs on the mailing list i have been able to re-create the repository using GIT as far back as revision 359.</p> <p>So what...]]></description>
		<content:encoded><![CDATA[<p>With the recent remakes of certain Lucasarts adventure games, i thought to myself &#8220;i wonder how the scummc compiler project is getting on?&#8221;</p>

<p>To my shock however, it seems the scummc website suddenly died sometime last year, so nobody was able to check out and learn from the only functioning third party SCUMM compiler.</p>

<p>Thankfully i was able to obtain a fairly recent copy of the files in the SVN repository, and coupled with the SVN commit logs on the mailing list i have been able to re-create the repository using GIT as far back as revision 359.</p>

<p>So what are you waiting for? Check it out on <a href='http://github.com/jamesu/scummc'>github</a>!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Don't write that framework</title>

		<link>http://www.cuppadev.co.uk/dont-write-that-framework/</link>
		<comments>http://www.cuppadev.co.uk/dont-write-that-framework/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=728</guid>
		<description><![CDATA[<p>Writing frameworks is a waste of time.</p> <p>That is the conclusion after spending most of my time on my last project <strong>writing a framework</strong>, in order to make the project &#8220;easier&#8221; to write.</p> <p>The trouble is every minute you divert to the framework, half of your project dies. And since there is an inherent division between project and framework, by the time you have everything working you have lost your original train of thought.</p> <p>Then you realize: the project is way <strong>behind schedule</strong>; there goes a cool feature that could have landed you a multitude of sales. Or even worse,...]]></description>
		<content:encoded><![CDATA[<p>Writing frameworks is a waste of time.</p>

<p>That is the conclusion after spending most of my time on my last project <strong>writing a framework</strong>, in order to make the project &#8220;easier&#8221; to write.</p>

<p>The trouble is every minute you divert to the framework, half of your project dies. And since there is an inherent division between project and framework, by the time you have everything working you have lost your original train of thought.</p>

<p>Then you realize: the project is way <strong>behind schedule</strong>; there goes a cool feature that could have landed you a multitude of sales. Or even worse, everyone has lost interest.</p>

<p>Instead, I suggest the following mode of thought:</p>

<ul>
<li>Find an existing framework that does most of what you require.&lt;/li&gt;</li>

<li>If the framework falls short, rethink your approach.&lt;/li&gt;</li>

<li>If you find your code has become a mess, re-factor it into a <strong>small</strong> library.&lt;/li&gt;</li>
</ul>

<p>Don&#8217;t be tempted to spend time writing a <strong>monolith</strong> of a framework. And beware the trap of thinking you can turn it into a product in itself; after all, there is a reason why a large proportion of frameworks are free.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Twackr: Twitter-style time tracking</title>

		<link>http://www.cuppadev.co.uk/twackr-twitter-style-time-tracking/</link>
		<comments>http://www.cuppadev.co.uk/twackr-twitter-style-time-tracking/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=718</guid>
		<description><![CDATA[<p>It&#8217;s been a while since my last rails post, so i decided to try out something different.</p> <p>Specifically, i&#8217;ve always wanted to track my time, but i never seem to find a solution that works. The solution is either too simple and doesn&#8217;t give me any feedback, or it&#8217;s extremely complicated and hard to use.</p> <p>So i set about to make a time tracking solution that was both ridiculously simple to use, and could give me some useful reports back. Thus, <a href='http://github.com/jamesu/twackr'>Twackr</a> was born!</p> <img alt='' class='alignnone size-thumbnail wp-image-720' height='158' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/02/twackr-2-300x158.png' title='Twackr' width='300' /> <p>I modelled the entry system...]]></description>
		<content:encoded><![CDATA[<p>It&#8217;s been a while since my last rails post, so i decided to try out something different.</p>

<p>Specifically, i&#8217;ve always wanted to track my time, but i never seem to find a solution that works. The solution is either too simple and doesn&#8217;t give me any feedback, or it&#8217;s extremely complicated and hard to use.</p>

<p>So i set about to make a time tracking solution that was both ridiculously simple to use, and could give me some useful reports back. Thus, <a href='http://github.com/jamesu/twackr'>Twackr</a> was born!</p>
<img alt='' class='alignnone size-thumbnail wp-image-720' height='158' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/02/twackr-2-300x158.png' title='Twackr' width='300' />
<p>I modelled the entry system after Twitter: at its simplest, all you need to do is type in what you are doing, and Twackr will start tracking your time instantly. When you are done, simply click on &#8220;Finish&#8221; and it will be done!</p>

<p>Already spent some time doing something but couldn&#8217;t get to Twackr? Then you can backdate entries by adding &#8221;<strong>-1H</strong>&#8221;. Still working on something? Then try &#8221;<strong>-1H+</strong>&#8221;. Blocking out some time? Then use &#8221;<strong>+1H</strong>&#8221;. Want to see if you&#8217;ll make the deadline? try typing &#8221;<strong>1H</strong>&#8221;.</p>

<p>Time can also be categorised into &#8220;Services&#8221; (<strong>#service</strong>) and &#8220;Projects&#8221; (<strong>@project</strong>).</p>

<p>You can check out a <a href='http://twackr.heroku.com/'>live demo of twackr on heroku</a>. Just sign up, and check it out - it couldn&#8217;t be any simpler!</p>

<p>Like most of my other rails projects, Twackr is Open Source. So feel free to <a href='http://github.com/jamesu/twackr'>fork it on github</a>.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>More CSS Animations</title>

		<link>http://www.cuppadev.co.uk/more-css-animations/</link>
		<comments>http://www.cuppadev.co.uk/more-css-animations/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=711</guid>
		<description><![CDATA[<p>A few days ago i popped across Anthony Calzadillas &#8221;<a href='http://anthonycalzadilla.com/css3-ATAT/index.html'>Pure CSS3 AT-AT Walker</a>&#8221;, which is a great application of using CSS3 Transforms and Animations to create a scene of an AT-AT Walker walking along in a simulated iPad.</p> <p>Anthony explains in great detail how he built the AT-AT, but i couldn&#8217;t help but think &#8221;I&#8217;ve got a better way of doing this!&#8221;.</p> <p>Last year i made a <a href='http://www.cuppadev.co.uk/projects/css-transform-exporter-for-blender/'>CSS Transform Exporter</a> for Blender, which can take any scene and generate a corresponding version in a nice and simple HTML page.</p> <p>So it can take this:</p> <a href='http://www.cuppadev.co.uk/wp-content/uploads/2010/02/atatblend.jpg'><img alt='atat in...]]></description>
		<content:encoded><![CDATA[<p>A few days ago i popped across Anthony Calzadillas &#8221;<a href='http://anthonycalzadilla.com/css3-ATAT/index.html'>Pure CSS3 AT-AT Walker</a>&#8221;, which is a great application of using CSS3 Transforms and Animations to create a scene of an AT-AT Walker walking along in a simulated iPad.</p>

<p>Anthony explains in great detail how he built the AT-AT, but i couldn&#8217;t help but think &#8221;I&#8217;ve got a better way of doing this!&#8221;.</p>

<p>Last year i made a <a href='http://www.cuppadev.co.uk/projects/css-transform-exporter-for-blender/'>CSS Transform Exporter</a> for Blender, which can take any scene and generate a corresponding version in a nice and simple HTML page.</p>

<p>So it can take this:</p>
<a href='http://www.cuppadev.co.uk/wp-content/uploads/2010/02/atatblend.jpg'><img alt='atat in blender' class='alignnone size-thumbnail wp-image-712' height='165' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/02/atatblend-300x165.jpg' title='atat in blender' width='300' /></a>
<p>And turn it into this:</p>
<a href='http://www.cuppadev.co.uk/wp-content/uploads/atat/atat.html'><img alt='atat webkit' class='alignnone size-thumbnail wp-image-713' height='200' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/02/atatwkit-251x200.jpg' title='atat webkit' width='251' /></a>
<p>Admittedly simple, but it does show off the potential power in adopting CSS3 and HTML5. After all, who needs to use Flash when you can make everything work in actual web browser instead?</p>]]></content:encoded>
	</item>
	
	<item>
		<title>The Ovi Store</title>

		<link>http://www.cuppadev.co.uk/the-ovi-store/</link>
		<comments>http://www.cuppadev.co.uk/the-ovi-store/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=693</guid>
		<description><![CDATA[<p>As any mobile app developer knows, there comes a time when you need to release your creations out to the general public. On the iPhone, one has the App Store. On Android, the Android Market. On Nokia devices, the Ovi Store.</p> <p>Whenever i hear someone talk about the Ovi Store, they never have <a href='http://www.techcrunch.com/2009/05/26/nokia-ovi-store-launch-is-a-complete-disaster/'>anything good</a> <a href='http://shkspr.mobi/blog/index.php/2009/05/nokia-ovi-store-oh-dear/'>to say</a> <a href='http://www.youtube.com/watch?v=UC8OC8XUZGg'>about it</a>. Having not experienced the store myself, i remained skeptical.</p> <p>Recently the Ovi Store on the <a href='http://maemo.nokia.com/n900/'>Nokia N900</a> opened, so naturally i decided to check it out and see if it really was as bad as people suggested....]]></description>
		<content:encoded><![CDATA[<p>As any mobile app developer knows, there comes a time when you need to release your creations out to the general public. On the iPhone, one has the App Store. On Android, the Android Market. On Nokia devices, the Ovi Store.</p>

<p>Whenever i hear someone talk about the Ovi Store, they never have <a href='http://www.techcrunch.com/2009/05/26/nokia-ovi-store-launch-is-a-complete-disaster/'>anything good</a> <a href='http://shkspr.mobi/blog/index.php/2009/05/nokia-ovi-store-oh-dear/'>to say</a> <a href='http://www.youtube.com/watch?v=UC8OC8XUZGg'>about it</a>. Having not experienced the store myself, i remained skeptical.</p>

<p>Recently the Ovi Store on the <a href='http://maemo.nokia.com/n900/'>Nokia N900</a> opened, so naturally i decided to check it out and see if it really was as bad as people suggested. What follows are my experiences, illustrated with accompanying screenshots.</p>
<h3>To Start</h3><img alt='Start Page' class='alignnone size-thumbnail wp-image-694' height='180' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/01/ovi1-300x180.png' title='Start Page' width='300' />
<p>First i tap on the &#8220;Ovi Store&#8221; icon on my device. After a short while, a <strong>web browser</strong> opens in fullscreen mode. So far, not bad.</p>

<p>Not sure what i want to do, i tap around the tabs (each <strong>loading a new page</strong>). Now i realise: i just saw something interesting on the last page, and want to see it again. But how do i go back? Well first i need to exit fullscreen mode. Next, i need to tap the back button. Then from the history list which appears: <img alt='Browser History' class='alignnone size-thumbnail wp-image-695' height='180' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/01/ovi2-300x180.png' title='Browser History' width='300' /></p>

<p>I must then select the previous slide. <strong>THEN</strong> if i am really unlucky, i get to see the page <strong>load again</strong>.</p>

<p>Now i decide i want to download a game, so i tap on the &#8220;Games&#8221; tab. The &#8220;Games&#8221; page <strong>loads</strong>, showing:</p>
<img alt='App List' class='alignnone size-thumbnail wp-image-696' height='180' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/01/ovi3-300x180.png' title='App List' width='300' />
<p>So now i think &#8221;I&#8217;ll try and download Angry Birds.&#8221; Herein lies a puzzling problem. <strong>Nothing happens</strong>. A few more taps, and the browser <strong>zooms in</strong>. Finally after a bit more tapping, i manage to get it to recognise i selected the app. The &#8220;Angry Birds&#8221; page loads.</p>
<img alt='Angry Birds Page' class='alignnone size-thumbnail wp-image-697' height='180' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/01/ovi4-300x180.png' title='Angry Birds Page' width='300' />
<p>Ok, so &#8220;Download&#8221;. But first i need to <strong>sign up</strong> for an Ovi Account!</p>
<img alt='OVI Signup' class='alignnone size-thumbnail wp-image-698' height='180' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/01/ovi5-300x180.png' title='OVI Signup' width='300' />
<p>After filling out all the forms, i get a &#8220;Thanks for signing up&#8221; page. By this time, i&#8217;ve <strong>all but forgotten</strong> what app i was going to purchase.</p>
<img alt='Browser History' class='alignnone size-thumbnail wp-image-695' height='180' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/01/ovi2-300x180.png' title='Browser History' width='300' />
<p>What would come in handy here would be&#8230; i don&#8217;t know, some sort of &#8220;Click here to continue your purchase&#8221; button perhaps? Instead, i have to use&#8230; the <strong>back button</strong>.</p>

<p>Finally, i tap the download button again. This time it loads the &#8220;Application Manager&#8221;, which after a while asks me if i want to continue installing &#8220;Angry Birds.&#8221;</p>
<img alt='App Download' class='alignnone size-thumbnail wp-image-699' height='180' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/01/ovi6-300x180.png' title='App Download' width='300' />
<p>At last, the app is installed. Eager to run it, i looked in my applications list, but couldn&#8217;t find it. Until i looked closer&#8230;</p>
<img alt='Find The App' class='alignnone size-thumbnail wp-image-701' height='180' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/01/ovi6.7-300x180.jpg' title='Find The App' width='300' />
<p>Yes, Angry Birds is represented by&#8230; a <strong>blue box</strong>.</p>

<p>Thankfully though, the app ran fine.</p>
<img alt='Running' class='alignnone size-thumbnail wp-image-700' height='180' src='http://www.cuppadev.co.uk/wp-content/uploads/2010/01/ovi7-300x180.png' title='Running' width='300' />
<p>All in all, i found the experience of downloading my free app to be unnecessarily frustrating. I can&#8217;t help but feel that nobody was really thinking when they designed the Ovi Store. From the constant page reloading, to the confusing appearance of the app on the device itself. I&#8217;d dread to think what would happen if i tried to buy an app.</p>

<p>I can safely say that currently the criticisms i have heard of the Ovi Store are well founded.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>CSS Transform Exporter for Blender</title>

		<link>http://www.cuppadev.co.uk/css-transform-exporter-for-blender/</link>
		<comments>http://www.cuppadev.co.uk/css-transform-exporter-for-blender/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=684</guid>
		<description><![CDATA[<p>Following on from <a href='http://www.cuppadev.co.uk/projects/creating-css-animations/'>Creating CSS Animations</a>, i have decided to release the exporter script used to create the animated orange test guy.</p> <p>As the title implies, the exporter script runs in Blender. Simply construct a 2D scene using planes, add in an animation track, run the script and click Export. It&#8217;s as simple as that!</p> <p>Each plane is exported as a HTML DIV. If present, any Ipos will be exported as CSS keyframes.</p> <p>The exporter even supports parenting, so you can build up complex hierarchies of elements which can easily be transformed in an animation, or even javascript.</p> <p>Note...]]></description>
		<content:encoded><![CDATA[<p>Following on from <a href='http://www.cuppadev.co.uk/projects/creating-css-animations/'>Creating CSS Animations</a>, i have decided to release the exporter script used to create the animated orange test guy.</p>

<p>As the title implies, the exporter script runs in Blender. Simply construct a 2D scene using planes, add in an animation track, run the script and click Export. It&#8217;s as simple as that!</p>

<p>Each plane is exported as a HTML DIV. If present, any Ipos will be exported as CSS keyframes.</p>

<p>The exporter even supports parenting, so you can build up complex hierarchies of elements which can easily be transformed in an animation, or even javascript.</p>

<p>Note that currently the exporter only supports Webkit-based browsers (i.e. Chrome, Safari, MobileSafari). It also has limited support for Firefox (sans animations).</p>

<p>For the curious, there are 3 examples:</p>
<ul>
<li><a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/12/walk.html'>Walking Orange Guy</a></li>
<li><a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/12/transformTest.html'>Transform Test (not animated)</a></li>
<li><a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/12/testImage.html'>Animated Image</a></li>
</ul>
<p>As for the actual exporter script, it&#8217;s <a href='http://github.com/jamesu/csstransformexport'>available on github</a>.</p>

<p>Happy animating!</p>
<strong>EDIT</strong>]]></content:encoded>
	</item>
	
	<item>
		<title>Thumbnails and Palettes in glgif </title>

		<link>http://www.cuppadev.co.uk/thumbnails-and-palettes-in-glgif/</link>
		<comments>http://www.cuppadev.co.uk/thumbnails-and-palettes-in-glgif/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=664</guid>
		<description><![CDATA[<p>Recently i incorporated support for creating thumbnails in <a href='http://github.com/jamesu/glgif'>glgif</a>, the backend gif animation library used in <a href='http://itunes.com/apps/anim8gif'>Anim8gif</a>.</p> <p>Rather than taking the easy route out and attempting to load the gif using UIImage, i decided to take advantage of glgif&#8217;s decode routines to create an accurate representation of the current state of the gif playback.</p> <p>Put simply, i took the palette texture which is generated for display, and decoded it into a new UIImage.</p> <p>The actual process is triggered by assigning a delegate (thumbDelegate), which will be invoked when the next frame in the gif is decoded. The delegate...]]></description>
		<content:encoded><![CDATA[<p>Recently i incorporated support for creating thumbnails in <a href='http://github.com/jamesu/glgif'>glgif</a>, the backend gif animation library used in <a href='http://itunes.com/apps/anim8gif'>Anim8gif</a>.</p>

<p>Rather than taking the easy route out and attempting to load the gif using UIImage, i decided to take advantage of glgif&#8217;s decode routines to create an accurate representation of the current state of the gif playback.</p>

<p>Put simply, i took the palette texture which is generated for display, and decoded it into a new UIImage.</p>

<p>The actual process is triggered by assigning a delegate (thumbDelegate), which will be invoked when the next frame in the gif is decoded. The delegate is then cleared.</p>

<p>Simple, right?</p>
<h3>More Technical Details</h3>
<p>The format of a palette texture in GLES is as follows:</p>
<table style='border: 2px solid grey;'>
<tr><td style='border: 2px solid black;padding: 3px;'>Palette (16 or 256 entries)</td><td style='border: 2px solid black;padding: 3px;'>Indexed Pixels (4bit or 8bit)</td></tr>
</table>
<p>The palette can either be 16 or 256 entries long, depending on the format you use. Likewise the pixel data will either use 4 bits or 8 bits. To keep things simple, glgif uses an 8bit palette with 3 8bit entries for the color (<strong>GL_PALETTE8_RGB8_OES</strong>).</p>

<p>(Note that an 8bit palette can be insufficient as a gif can actually display more than 256 colours across multiple frames, but this is a necessary trade-off for speed)</p>

<p>So in order to decode it: <ol>
<li>Read and decode the palette</li>
<li>Decode each pixel as an index into the palette</li>
<li>Using the decoded pixel data, create a new CoreGraphics bitmap context (using <strong>CGBitmapContextCreate</strong>)</li>
<li>Convert the bitmap context into a UIImage (using <strong>CGBitmapContextCreateImage</strong> and <strong>[UIImage imageWithCGImage:]</strong>)</li>
</ol></p>

<p>The resultant UIImage can then easily be used as a base to generate a sized down thumbnail of the gif, as illustrated below.</p>
<img alt='Example gif thumbnail' class='alignnone size-full wp-image-665' height='480' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/12/ex-thumbnails.png' title='Example gif thumbnail' width='320' />
<p>As always, the code for glgif is <a href='http://github.com/jamesu/glgif'>hosted on github</a>, so feel free to check it out!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Creating CoreAnimation Animations</title>

		<link>http://www.cuppadev.co.uk/creating-coreanimation-animations/</link>
		<comments>http://www.cuppadev.co.uk/creating-coreanimation-animations/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=659</guid>
		<description><![CDATA[<p>Moving on from <a href='http://www.cuppadev.co.uk/projects/creating-css-animations/'>Creating CSS Animations</a>, i thought <em>"How can i make this exporter more useful?"</em>.</p> <p>The answer is of course to completely remove Webkit from the equation, which leaves us with CoreAnimation. The end result being that the animation can be directly compiled into an iPhone or Mac OS X application.</p> <p>Not going <a href='http://www.opensource.apple.com/source/WebCore/WebCore-514/platform/graphics/mac/GraphicsLayerCA.mm'>into much detail</a>, <a href='http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/CoreAnimation_guide/Articles/WhatisCoreAnimation.html'>CoreAnimation</a> is essentially the library used by Webkit to display and animate any elements which have been transformed by a CSS Transform.</p> <p>The actual scene is simply constructed using transformed <strong>CALayers</strong>. As for the animation, a <strong>CAKeyframeAnimation</strong> is created and...]]></description>
		<content:encoded><![CDATA[<p>Moving on from <a href='http://www.cuppadev.co.uk/projects/creating-css-animations/'>Creating CSS Animations</a>, i thought <em>"How can i make this exporter more useful?"</em>.</p>

<p>The answer is of course to completely remove Webkit from the equation, which leaves us with CoreAnimation. The end result being that the animation can be directly compiled into an iPhone or Mac OS X application.</p>

<p>Not going <a href='http://www.opensource.apple.com/source/WebCore/WebCore-514/platform/graphics/mac/GraphicsLayerCA.mm'>into much detail</a>, <a href='http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/CoreAnimation_guide/Articles/WhatisCoreAnimation.html'>CoreAnimation</a> is essentially the library used by Webkit to display and animate any elements which have been transformed by a CSS Transform.</p>

<p>The actual scene is simply constructed using transformed <strong>CALayers</strong>. As for the animation, a <strong>CAKeyframeAnimation</strong> is created and attached to each <strong>CALayer</strong>. In the case of multiple properties being animated at the same time, a <strong>CAAnimationGroup</strong> is used to group these animations together.</p>

<p>The end result is a handy animation class which creates both the scene and the related animation tracks. i.e.:</p>

<pre><code>CALayer *root = [self.view layer];

// Make anim
MyAnim *anim = [[MyAnim alloc] init];
CALayer *animRoot = anim.root;
[root addSublayer:animRoot];

[anim play]; // easy!</code></pre>

<p>As an example, the MyAnim class for the previously featured walking orange figure is as follows.</p>
<script src='http://gist.github.com/242862.js?file=Walking+CoreAnimation+Guy.m'>;</script>
<p>Which leads onto a repeat of the question, is there a real-world demand for such a tool yet?</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Creating CSS Animations</title>

		<link>http://www.cuppadev.co.uk/creating-css-animations/</link>
		<comments>http://www.cuppadev.co.uk/creating-css-animations/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=645</guid>
		<description><![CDATA[<p>CSS <a href='http://webkit.org/blog/130/css-transforms/'>Transforms</a> combined with <a href='http://webkit.org/blog/138/css-animation/'>animations</a> are undoubtedly useful. Unfortunately though, the only way to create them is to manually input values and pretty much guess the result.</p> <p>This methodology pretty much kills any creative aspirations anyone might have in making these animations. So while there are quite a few <a href='http://girliemac.com/blog/2009/09/03/webkit-css-3d-local-db-demo/'>cool</a> <a href='http://www.satine.org/research/webkit/snowleopard/snowstack.html'>looking</a> examples out there they lack the glamour of say, <a href='http://www.weebls-stuff.com/'>flash animations</a>.</p> <p>It seems to me there is a need for a tool which allows anyone to create these css animations in a visual way. As far as i know, no such tool currently exists....]]></description>
		<content:encoded><![CDATA[<p>CSS <a href='http://webkit.org/blog/130/css-transforms/'>Transforms</a> combined with <a href='http://webkit.org/blog/138/css-animation/'>animations</a> are undoubtedly useful. Unfortunately though, the only way to create them is to manually input values and pretty much guess the result.</p>

<p>This methodology pretty much kills any creative aspirations anyone might have in making these animations. So while there are quite a few <a href='http://girliemac.com/blog/2009/09/03/webkit-css-3d-local-db-demo/'>cool</a> <a href='http://www.satine.org/research/webkit/snowleopard/snowstack.html'>looking</a> examples out there they lack the glamour of say, <a href='http://www.weebls-stuff.com/'>flash animations</a>.</p>

<p>It seems to me there is a need for a tool which allows anyone to create these css animations in a visual way. As far as i know, no such tool currently exists. So naturally, i set about making something myself.</p>

<p>Rather than make an entire tool from scratch though, i decided to simply write an exporter script for another tool - in this case, <a href='http://www.blender.org'>Blender</a>.</p>

<p>Why Blender? Well, it exposes pretty much all of the information i require to construct both a scene and animation tracks. Also, since Blender handles 3D scenes, there is a potential to work with <a href='http://webkit.org/blog/386/3d-transforms/'>3D CSS Transforms</a> in the future.</p>

<p>As an example, here&#8217;s a simple animation of an orange stick man walking across the screen. The stick man was both constructed and animated entirely within Blender, and exported using my export script.</p>
<a href='http://stuff.cuppadev.co.uk/walk.html'><img alt='example-walk' class='alignnone size-thumbnail wp-image-649' height='200' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/11/example-walk-268x200.png' title='example-walk' width='268' /></a>
<p>And the scene as seen in blender:</p>
<a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/11/Screen-shot-2009-11-22-at-22.19.24.png'><img alt='Example animation in Blender' class='alignnone size-thumbnail wp-image-648' height='192' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/11/Screen-shot-2009-11-22-at-22.19.24-300x192.png' title='Example animation in Blender' width='300' /></a>
<p>Which is simply a set of planes linked together and animated. Really, it couldn&#8217;t be any simpler.</p>

<p>Currently the only browsers which seem to support both CSS transforms and animations are based off <a href='http://www.webkit.org'>Webkit</a>. i.e. Safari and Chrome (including the iPhone and Android browsers).</p>

<p>Which leads onto the question, is there a real-world demand for such a tool yet?</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Making Money in the App Store: I Give Up</title>

		<link>http://www.cuppadev.co.uk/making-money-in-the-app-store-i-give-up/</link>
		<comments>http://www.cuppadev.co.uk/making-money-in-the-app-store-i-give-up/#comments</comments>
		<pubDate>Sat, 14 Nov 2009 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=628</guid>
		<description><![CDATA[<p>After almost a year of developing a and releasing a handful of iPhone apps to the <a href='http://itunes.apple.com/'>App Store</a>, i should be <a href='http://appadvice.com/appnn/2009/02/ishoot-developer-makes-600000-in-one-month/'>rolling</a> <a href='http://www.edibleapple.com/ifart-developer-makes-40000-in-2-days/'>in</a> <a href='http://www.businessinsider.com/2008/9/iphone-developer-i-ll-do-anything-apple-tells-me-to-do-i-just-made-250k-on-the-app-store-in-two-months-aapl-'>money</a>, right?</p> <p>Wrong.</p> <p>In fact, i can officially reveal that with the exception of development contracts, my iPhone apps have netted me a grand total of:</p> <p style='font-size: 32px; font-weight: bold;'>£0</p> <p>Yes, <strong>£0</strong>. It takes a lot of face up to facts, but it can&#8217;t be much more blunt than that. Granted i did sell a few units, but these were nowhere near the amount required to release any real payment into my...]]></description>
		<content:encoded><![CDATA[<p>After almost a year of developing a and releasing a handful of iPhone apps to the <a href='http://itunes.apple.com/'>App Store</a>, i should be <a href='http://appadvice.com/appnn/2009/02/ishoot-developer-makes-600000-in-one-month/'>rolling</a> <a href='http://www.edibleapple.com/ifart-developer-makes-40000-in-2-days/'>in</a> <a href='http://www.businessinsider.com/2008/9/iphone-developer-i-ll-do-anything-apple-tells-me-to-do-i-just-made-250k-on-the-app-store-in-two-months-aapl-'>money</a>, right?</p>

<p>Wrong.</p>

<p>In fact, i can officially reveal that with the exception of development contracts, my iPhone apps have netted me a grand total of:</p>
<p style='font-size: 32px; font-weight: bold;'>£0</p>
<p>Yes, <strong>£0</strong>. It takes a lot of face up to facts, but it can&#8217;t be much more blunt than that. Granted i did sell a few units, but these were nowhere near the amount required to release any real payment into my bank account.</p>
<h3>So what went wrong?</h3>
<p>Well to be quite honest, i didn&#8217;t really market my apps at all well. I was hoping that simply being in the App Store combined with a word-of-mouth viral networking effect combined with some online ads would be sufficient. From there i could perhaps get some feedback, and introduce improvements in line with demand.</p>

<p>Did it work? <strong>Far from it</strong>.</p>

<p>Sadly since the iPhone market is pretty much <strong>saturated</strong> with thousands of apps, this is pretty much impossible to accomplish. You&#8217;d probably have more chance winning the lottery than going with that approach.</p>

<p>I even tried making one of my apps free and promoting one of my paid apps in the description. The actual response in sales was negligible.</p>

<p>It seems to me the only viable ways of attracting people to a new app are:</p>
<ol>
<li>Getting it <strong>featured</strong> on the App Store</li>
<li>Pushing it out to as many <strong>review sites</strong> as you can ahead of time</li>
<li>Making it <strong>free</strong></li>
</ol>
<p>With regards to #3, not getting into in-depth analysis i will say this: if you have an app with a remotely useful purpose, people will consistently download it.</p>

<p>For example one of my apps, <a href='http://itunes.apple.com/apps/anim8gif'>Anim8gif</a>, gets at least 20 downloads a week - mind you, that figure isn&#8217;t really useful since none of those 20 people bother to write a review or send any useful feedback.</p>

<p>Right now though, i&#8217;m a bit tired of spending my budget coming up with the next big idea with elaborate marketing that&#8217;s likely to bring in tons of revenue. So here&#8217;s what i&#8217;m going to do.</p>

<p>I&#8217;m just giving up on making money off my own iPhone apps altogether. All my current apps: <a href='http://itunes.com/apps/anim8gif'>Anim8gif</a>, <a href='http://itunes.com/apps/vidsplit'>VidSplit</a>, and <a href='http://itunes.com/apps/overthecam'>Overthecam</a> are now free.</p>

<p>As for making future free apps, i am still undecided. Am i really getting anything out of the experience? Current signs point to no.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>The Trouble with CSS Transitions</title>

		<link>http://www.cuppadev.co.uk/the-trouble-with-css-transitions/</link>
		<comments>http://www.cuppadev.co.uk/the-trouble-with-css-transitions/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=587</guid>
		<description><![CDATA[<p>Recently in a little experiment, i made a rather cool demo which makes use of CSS Transforms, combined with CSS Transitions.</p> <p><em>Note:</em> Examples only work in Safari 4+, or other recent webkit-based browsers.</p> <a href='/assets/iphone/css-transitions/feet.html' target='_blank'><img alt='Footprint Demo' class='alignnone size-thumbnail wp-image-612' height='200' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/10/Screen-shot-2009-10-23-at-19.52.17-266x200.png' title='Footprint Demo' width='266' /></a> <p>&#8221;<em>Cool</em>?&#8221; you say. Well admittedly i could have gone for something <a href='http://harrypotter.wikia.com/wiki/Marauder&apos;s_Map'>a bit more elaborate</a>, however as it stands it pretty much serves its purpose - that is to demonstrate that using the magic of CSS Transitions you can create fast, useful web effects which run at acceptable framerates on an iPhone,...]]></description>
		<content:encoded><![CDATA[<p>Recently in a little experiment, i made a rather cool demo which makes use of CSS Transforms, combined with CSS Transitions.</p>

<p><em>Note:</em> Examples only work in Safari 4+, or other recent webkit-based browsers.</p>
<a href='/assets/iphone/css-transitions/feet.html' target='_blank'><img alt='Footprint Demo' class='alignnone size-thumbnail wp-image-612' height='200' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/10/Screen-shot-2009-10-23-at-19.52.17-266x200.png' title='Footprint Demo' width='266' /></a>
<p>&#8221;<em>Cool</em>?&#8221; you say. Well admittedly i could have gone for something <a href='http://harrypotter.wikia.com/wiki/Marauder&apos;s_Map'>a bit more elaborate</a>, however as it stands it pretty much serves its purpose - that is to demonstrate that using the magic of CSS Transitions you can create fast, useful web effects which run at acceptable framerates on an iPhone, and even on the desktop (since the tweening of properties is done by the browser).</p>

<p>However to get this admittedly simple demo working, i had to battle through a few odd issues with how these transitions operate.</p>
<h3>The problems</h3>
<p>To start off, resetting transitions is a bit tricky. Since properties are not processed immediately, you need to wait for the browser to detect you have reset transition values before you transition to any new values.</p>

<p>Thankfully a nice event called <strong>webkitTransitionEnd</strong> is provided which is fired as soon as a transition is complete, so you could conceivably use it to handle resetting the transition.</p>

<p>The only problem? <strong>webkitTransitionEnd</strong> seems to only fire when it feels like it.</p>
<a href='/assets/iphone/css-transitions/circles.html' target='_blank'><img alt='Circles Demo' class='alignnone size-thumbnail wp-image-611' height='200' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/10/Screen-shot-2009-10-23-at-19.47.11-172x200.png' title='Circles Demo' width='172' /></a>
<p>The above example demonstrates the peculiarity of <strong>webkitTransitionEnd</strong>. The green/pink circle is meant to change colour every time the event is fired. Since there is an interval running every 100ms which changes the rotation of the circles, what typically happens 99.9% of the time is the transition never really ends, thus no event.</p>

<p>In general, the transition event seems to behave as follows:</p>
<table>
<tr><th>Setting...</th><th>Result</th></tr>
<tr><td>Initial transition (element just created)</td><td><strong style='color:red'>FAIL</strong></td></tr>
<tr><td>Transition continuously (during transition)</td><td><strong style='color:yellow'>MOSTLY FAIL</strong></td></tr>
<tr><td>Transition after a sufficient undefined delay</td><td><strong style='color:green'>PASS</strong></td></tr>
</table>
<p>So safe to say, unless you&#8217;ve got a transition you aren&#8217;t going to mess about with then don&#8217;t rely on <strong>webkitTransitionEnd</strong>.</p>
<h3>Onto quirky platforms...</h3>
<p>Finally, with regard to the iPhone platform there are even more quirks. Compared to desktop Safari, the tweening acts quite differently.</p>

<p>One notable quirk is if you make a new element with a transition on Desktop safari, it performs that transition. If however you do the <strong>same</strong> thing on Mobile Safari, the transition starts at the <strong>end</strong>. Whether or not this is some bizarre timing issue, i have no idea.</p>

<p>So safe to say, while CSS Transitions are a powerful tool to use, beware of the quirks.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Displaying Image Hints on an iPhone</title>

		<link>http://www.cuppadev.co.uk/displaying-image-hints-on-an-iphone/</link>
		<comments>http://www.cuppadev.co.uk/displaying-image-hints-on-an-iphone/#comments</comments>
		<pubDate>Sun, 11 Oct 2009 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=578</guid>
		<description><![CDATA[<p>Recently it has come to my attention that there is no way to view hints on images on an iPhone.</p> <p>Normally on any modern desktop web browser when you hover your mouse cursor over an image, a hint if provided will be displayed. Certain <a href='http://www.xkcd.com'>websites</a> use these hints to comedic effect, and it&#8217;s a shame you can&#8217;t see them.</p> <img class='alignnone size-full wp-image-579' height='120' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/10/Screen-shot-2009-10-11-at-11.53.04.png' title='great!' width='279' /> <p>Fortunately i have come up with a nice and simple bookmarklet to solve this issue. Simply add it to your bookmarks in Safari, sync over to your iPhone and run the...]]></description>
		<content:encoded><![CDATA[<p>Recently it has come to my attention that there is no way to view hints on images on an iPhone.</p>

<p>Normally on any modern desktop web browser when you hover your mouse cursor over an image, a hint if provided will be displayed. Certain <a href='http://www.xkcd.com'>websites</a> use these hints to comedic effect, and it&#8217;s a shame you can&#8217;t see them.</p>
<img class='alignnone size-full wp-image-579' height='120' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/10/Screen-shot-2009-10-11-at-11.53.04.png' title='great!' width='279' />
<p>Fortunately i have come up with a nice and simple bookmarklet to solve this issue. Simply add it to your bookmarks in Safari, sync over to your iPhone and run the bookmarklet.</p>
<img alt='Simply genius!' class='alignnone size-full wp-image-580' height='264' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/10/Screen-shot-2009-10-11-at-11.53.19.png' title='Simply genius!' width='294' />
<p>To view a hint, simply hold down two fingers over an image. The associated hint will be displayed in a pop-up alert.</p>
<pre class='markdown-html-error' style='border: solid 3px red; background-color: pink'>REXML could not parse this XML/HTML: 
&lt;a href=&quot;javascript:function%20registerImg(img)%20{var%20timer%20=%20null;function%20ts(e)%20{if%20(e.touches.length%20&lt;%202)return;e.preventDefault();timer%20=%20setTimeout(function(){alert(img.getAttribute(%22title%22));},500);}function%20te(e)%20{e.preventDefault();clearTimeout(timer);}img.ontouchstart%20=%20ts;img.ontouchend%20=%20img.ontouchcancel%20=%20te;}var%20i,imgs%20=%20document.querySelectorAll(%22img%22);for%20(i=0;i&lt;imgs.length;i++)%20registerImg(imgs[i]);&quot;&gt;Drag this link&lt;/a&gt;</pre>
<p>Or you can check out the full code in <a href='http://gist.github.com/207094'>this gist</a>.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>A Browser within a Browser: HtmlCanvas</title>

		<link>http://www.cuppadev.co.uk/a-browser-within-a-browser-htmlcanvas/</link>
		<comments>http://www.cuppadev.co.uk/a-browser-within-a-browser-htmlcanvas/#comments</comments>
		<pubDate>Thu, 08 Oct 2009 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=565</guid>
		<description><![CDATA[<p>It&#8217;s been a while since my last <a href='http://www.cuppadev.co.uk/2007/11/22/flash-plays-scumm-take-two/'>truly silly</a> project, so i thought i&#8217;d come up with something else.</p> <p>There has been <a href='http://carsonified.com/blog/web-apps/introducing-atlas-a-visual-development-tool-for-creating-web-apps/'>a lot of talk</a> recently about how the web is essentially replacing desktop applications, which to me sounds great.</p> <p>But there is something missing from this new age of web applications. In order to run web apps you need a web browser, which is still a desktop app. It seems to me odd that a platform which replaces another still requires that platform to operate.</p> <p>Which is where <a href='http://github.com/jamesu/htmlcanvas'>htmlcanvas</a> comes in. It&#8217;s a HTML renderer...]]></description>
		<content:encoded><![CDATA[<p>It&#8217;s been a while since my last <a href='http://www.cuppadev.co.uk/2007/11/22/flash-plays-scumm-take-two/'>truly silly</a> project, so i thought i&#8217;d come up with something else.</p>

<p>There has been <a href='http://carsonified.com/blog/web-apps/introducing-atlas-a-visual-development-tool-for-creating-web-apps/'>a lot of talk</a> recently about how the web is essentially replacing desktop applications, which to me sounds great.</p>

<p>But there is something missing from this new age of web applications. In order to run web apps you need a web browser, which is still a desktop app. It seems to me odd that a platform which replaces another still requires that platform to operate.</p>

<p>Which is where <a href='http://github.com/jamesu/htmlcanvas'>htmlcanvas</a> comes in. It&#8217;s a HTML renderer implemented in JavaScript, which runs nicely in any capable web browser which supports the <a href='http://en.wikipedia.org/wiki/Canvas_(HTML_element)'>Canvas</a> element.</p>
<a href='http://jamesu.github.com/htmlcanvas'><img alt='htmlcanvas in action' class='alignnone size-full wp-image-566' height='170' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/10/Screen-shot-2009-10-08-at-19.46.56.png' title='htmlcanvas in action' width='302' /></a>
<p>In essence, it&#8217;s a web browser implemented within a web browser. The above example was rendered from this HTML:</p>
<pre>
<code>
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;&lt;!-- Begin test --&gt;
  &lt;p class=&quot;woo&quot; id=&quot;render&quot;&gt;
Rendering &lt;b&gt;HTML&lt;/b&gt;...&lt;/p&gt;
  &lt;p&gt;&lt;span&gt;In &lt;b&gt;Canvas&lt;/b&gt;&lt;/span&gt;!&lt;/p&gt;
  &lt;p&gt;0_0&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</code>
</pre>
<p>This sort of recursive abstraction is not uncommon in the computing world. For example, C compilers are <a href='http://gcc.gnu.org/'>written in C</a>, Pascal compilers are <a href='http://www.freepascal.org/'>written in Pascal</a>. There&#8217;s even a version of <a href='http://codespeak.net/pypy/dist/pypy/doc/'>Python implemented within Python</a>. So a web platform implemented within a web platform is quite natural.</p>

<p>Still, it will be a long while before htmlcanvas is remotely capable of running within itself, so a truly recursive web browsing experience is still a long way off.</p>

<p>As with most of my silly projects, the code to htmlcanvas is hosted on github. Fork it <a href='http://github.com/jamesu/htmlcanvas'>here</a>!</p>

<p><em>Note:</em>: Currently only known to work in Safari 4, FireFox 3.5, or Google Chrome.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>The Mystery of Jekyll</title>

		<link>http://www.cuppadev.co.uk/the-mystery-of-jekyll/</link>
		<comments>http://www.cuppadev.co.uk/the-mystery-of-jekyll/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=545</guid>
		<description><![CDATA[<p>I recently stumbled across the much-loved <a href='http://jekyllrb.com/'>Jekyll</a>, a &#8220;blog aware&#8221; website generator.</p> <p>I say &#8220;blog aware&#8221; since i have yet to be convinced it is. Jekyll seems to work fine if you have a flat layout of _posts with topics, but as soon as you stray away from that, it begins to fall apart.</p> <h3>An Example</h3> <p>I&#8217;ll give you a real world example. This blog. Simply enough, i&#8217;ve got posts organised into categories. I&#8217;ve also got a few tags on the posts, though they are mainly intended for the website feed. After reading the Jekyll documentation, it says:</p> <blockquote>Categories...]]></description>
		<content:encoded><![CDATA[<p>I recently stumbled across the much-loved <a href='http://jekyllrb.com/'>Jekyll</a>, a &#8220;blog aware&#8221; website generator.</p>

<p>I say &#8220;blog aware&#8221; since i have yet to be convinced it is. Jekyll seems to work fine if you have a flat layout of _posts with topics, but as soon as you stray away from that, it begins to fall apart.</p>
<h3>An Example</h3>
<p>I&#8217;ll give you a real world example. This blog. Simply enough, i&#8217;ve got posts organised into categories. I&#8217;ve also got a few tags on the posts, though they are mainly intended for the website feed. After reading the Jekyll documentation, it says:</p>
<blockquote>Categories are derived from the directory structure above the _posts directory. For example, a post at /work/code/_posts/2008-12-24-closures.textile would have this field set to ['work', 'code']."
</blockquote>
<p>So i think &#8221;<em>right, i'll make folders for my existing categories then stick their posts into each respective _posts folder</em>&#8221;.</p>
<img alt='ex-folders' class='alignnone size-full wp-image-557' height='70' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/10/ex-folders.png' title='ex-folders' width='256' />
<p>This actually works rather well: if i list <strong>&#123;&#123; site.posts &#125;&#125;</strong> from <strong>/index.html</strong>, each post gets listed with their .categories attribute set.</p>
<img alt='ex-bug' class='alignnone size-full wp-image-546' height='54' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/10/ex-bug.png' title='ex-bug' width='480' />
<p>However if i list a posts <strong>.categories</strong> in the actual post, the list is mysteriously <strong>empty</strong>. It&#8217;s like Jekyll decided to make the categories act as some weird reverse breadcrumb system. Why this would be remotely useful, i have no idea.</p>

<p>The problem with how posts are listed gets further compounded when you start to use topics. All of my real blog posts are tagged &#8220;blog&#8221;, so in order to list them i actually use <strong>site.topics.blog</strong>. This works fine, until i try and list posts from within a &#8220;category&#8221;.</p>

<p>For some bizarre reason, the list of posts varies depending on which category you list from. For example, i have a <strong>/feed</strong> folder which contains an rss feed template. The only posts listed in the feed are those in my &#8220;dev&#8221; topic.</p>

<p>My only guess is that since alphabetically &#8220;d&#8221; comes before &#8220;f&#8221;, Jekyll is going through each category <strong>one-by-one</strong> and making posts on-the-fly. Pre-processing? We don&#8217;t need pre-processing!</p>

<p>The only real solution seems to be to store all of your posts in the top-level _posts folder, but that sort of defeats the purpose of using a folder-based category system.</p>
<h3>Onto pagination and beyond!</h3>
<p>Now assuming you have got your posts sorted out, you&#8217;ll probably want to paginate them, right? Well good luck with that; while Jekyll will allow you to split posts up into pages, the paginator is a global option. So if you want pages, you&#8217;ve got to have pages on everything.</p>

<p>Got multiple lists of posts on a single page? Well watch out, you could be in for a nasty surprise!</p>

<p>Which brings me onto the rather limited Liquid markup Jekyll uses. Now i don&#8217;t have much of an issue with the <a href='http://www.liquidmarkup.org/'>Liquid markup</a> itself, after all i thought it was used rather well in <a href='http://mephistoblog.com/'>Mephisto</a>.</p>

<p>But in Jekyll, i&#8217;m constantly trying to find a workaround for its rather limited set of liquid tags. Want to list posts by date? How about multiple tags? Good luck with that!</p>

<p>So safe to say, unless you have a pretty simple blog with a flat layout then out-of-the-box Jekyll quite simply doesn&#8217;t cut it yet - sad but true.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Frozen Synapse... on a Mac!</title>

		<link>http://www.cuppadev.co.uk/frozen-synapse-on-a-mac/</link>
		<comments>http://www.cuppadev.co.uk/frozen-synapse-on-a-mac/#comments</comments>
		<pubDate>Wed, 26 Aug 2009 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=538</guid>
		<description><![CDATA[<a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/08/synapse.jpg'><img alt='Frozen Synapse!' class='alignnone size-medium wp-image-539' height='231' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/08/synapse-300x231.jpg' title='Frozen Synapse!' width='300' /></a> <p>Yes indeed, it&#8217;s <strong>Frozen Synapse</strong>&#8230; Running on a mac.</p> <p>&#8220;What is <strong>Frozen Synapse</strong>?&#8221;, you may ask. Well it&#8217;s nothing to do with web development. Nor ruby or rails. Nor even JavaScript for that matter!</p> <p>Put simply, it&#8217;s a great new <a href='http://www.frozensynapse.com'>tactical strategy game from Mode 7 Games</a>!</p> <p>Unfortunately it&#8217;s still in development, so it&#8217;ll be a while till the general public can get its hands on the awesomeness of this game. Still, when it&#8217;s available you&#8217;ll be sure to find a nice mac version.</p> <p>So until...]]></description>
		<content:encoded><![CDATA[<a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/08/synapse.jpg'><img alt='Frozen Synapse!' class='alignnone size-medium wp-image-539' height='231' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/08/synapse-300x231.jpg' title='Frozen Synapse!' width='300' /></a>
<p>Yes indeed, it&#8217;s <strong>Frozen Synapse</strong>&#8230; Running on a mac.</p>

<p>&#8220;What is <strong>Frozen Synapse</strong>?&#8221;, you may ask. Well it&#8217;s nothing to do with web development. Nor ruby or rails. Nor even JavaScript for that matter!</p>

<p>Put simply, it&#8217;s a great new <a href='http://www.frozensynapse.com'>tactical strategy game from Mode 7 Games</a>!</p>

<p>Unfortunately it&#8217;s still in development, so it&#8217;ll be a while till the general public can get its hands on the awesomeness of this game. Still, when it&#8217;s available you&#8217;ll be sure to find a nice mac version.</p>

<p>So until then, keep your eyes peeled for Frozen Synapse!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>The Horror of Android Development</title>

		<link>http://www.cuppadev.co.uk/the-horror-of-android-development/</link>
		<comments>http://www.cuppadev.co.uk/the-horror-of-android-development/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=508</guid>
		<description><![CDATA[<p>Back when the Android SDK was first released, i thought i&#8217;d check it out. Turns out there was a <a href='http://code.google.com/android/adc/'>google competition</a> where you could win cash prizes for making android apps. <em>"Simple!"</em>, i thought. That was until i looked further at the SDK and found it to be far too incomplete and with little documentation.</p> <p>Safe to say, i didn&#8217;t make an Android app.</p> <p>Recently, the has been another Google competition so i thought i&#8217;d check out the SDK. <em>"It's bound to be far more mature and usable!"</em>, i thought (not to mention it&#8217;s supposed to be the greatest...]]></description>
		<content:encoded><![CDATA[<p>Back when the Android SDK was first released, i thought i&#8217;d check it out. Turns out there was a <a href='http://code.google.com/android/adc/'>google competition</a> where you could win cash prizes for making android apps. <em>"Simple!"</em>, i thought. That was until i looked further at the SDK and found it to be far too incomplete and with little documentation.</p>

<p>Safe to say, i didn&#8217;t make an Android app.</p>

<p>Recently, the has been another Google competition so i thought i&#8217;d check out the SDK. <em>"It's bound to be far more mature and usable!"</em>, i thought (not to mention it&#8217;s supposed to be the greatest platform in the world to develop for). Unfortunately, it was just as bad as it was the last time i looked at it. <h3>The Problems</h3> Firstly, it&#8217;s based on Java, which <a href='http://en.wikipedia.org/wiki/Dalvik_virtual_machine'>isn't really Java</a>. Even so, it inherits all of Java&#8217;s problems. A weird and nonsensical class hierarchy for one. The overuse of abstraction for fairly simple API&#8217;s is another. Not to mention, the overload of XML files, which seem to permeate everything you do for no good reason.</p>

<p>In general i&#8217;d probably call it a rewrite of <a href='http://en.wikipedia.org/wiki/J2ME'>J2ME</a>, only 10 times worse. Why worse? well at least with any decent J2ME SDK, you usually get some sort of usable GUI builder. Instead with Android, you get this mess&#8230; <p style='text-align: center;'><a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/08/Picture-2.png'><img alt='GUI Builder Horror' class='size-thumbnail wp-image-520 aligncenter' height='159' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/08/Picture-2-300x159.png' title='GUI Builder Horror' width='300' /></a></p></p>

<p>Seriously, it&#8217;s the 21st century and i&#8217;m reduced to building a GUI <a href='http://thedailywtf.com/Articles/BlackBerry-UI-Magic.aspx'>using a spreadsheet</a> and dragging a few nondescript labels around the screen in the vain attempt to build something which actually looks good. It&#8217;s so bad, even the tutorials <a href='http://developer.android.com/guide/tutorials/notepad/notepad-ex1.html'>recommend editing XML files</a> rather than using it.</p>

<p>Earth to Android: people were making far better gui builders <a href='http://en.wikipedia.org/wiki/Nextstep'>as early as 1989</a>.</p>

<p>The distributed emulator application doesn&#8217;t exactly instil me with confidence either. Not only do i have to wait 5 minutes for it to boot up, it&#8217;s also horrifically slow for anything other than a simple &#8220;Hello World&#8221; application. <p style='text-align: center;'><a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/08/Picture-3.png'><img alt='Android Emulator' class='size-thumbnail wp-image-524 aligncenter' height='200' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/08/Picture-3-240x200.png' title='Android Emulator' width='240' /></a></p></p>

<p>Seriously, if Android is supposed to be <a href='http://www.kandroid.org/android_pdk/source_setup_guide.html'>OS agnostic</a>, why not make a simulated environment rather than a whole emulator? Would be a whole lot faster and usable if you ask me!</p>

<p>And of course, the real killer. The preferred IDE is&#8230;</p>
<a href='http://www.eclipse.org'>Eclipse</a>
<p>If you asked a bunch of random strangers to build a bridge, you&#8217;d get a hideous construction which leads nowhere. In a similar vein, Eclipse is built by a complete bunch of strangers and ends up being an unusable mess. What&#8217;s worse is they&#8217;ve had 3 whole versions to sort it out, and rather than getting better it seems to be turning into an increasingly bloated mess.</p>

<p>I&#8217;ll give you an example. The code window is by default cramped in the middle of the window, it&#8217;s like looking through a keyhole to get at your code. Want to find the configuration settings? Good luck. You&#8217;ll have to dig through a whole myriad of menus just to <a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/08/Picture-6.png' target='_blank'>change the font size</a>.</p>

<p>Lets not forget the quirks. Want to scroll through a list using a mouse wheel? Well you&#8217;d better watch out for those <a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/08/Picture-7.png' target='_blank'>pesky hint boxes</a> which pop up and completely block focus.</p>

<p>But i digress; continuing with the Android SDK, another issue i have is with the actual documentation. Most of the time it follows a policy of listing what i can do, but not giving me any good examples of how to do it.</p>

<p>I&#8217;ll give you an example, looking at the &#8221;<a href='http://developer.android.com/intl/zh-CN/guide/topics/graphics/opengl.html'>3D with OpenGL</a>&#8221; section: <blockquote>"Writing a summary of how to actually write 3D applications using OpenGL is beyond the scope of this text and is left as an exercise for the reader."</blockquote> Want to write OpenGL applications? We&#8217;ll just vaguely describe how you could do it and just leave you to guess it all out on your own. Not that your app will be usable on all devices of course.</p>

<p>It also likes to mention technologies with little to no explanation of what they do. Taking the &#8221;<a href='http://developer.android.com/guide/topics/media/index.html'>Audio and Video</a>&#8221; section as an example, a reference is made to &#8220;Playing JET content&#8221;. What is &#8220;JET content&#8221;? I seriously have no idea.</p>

<p>Not to mention, there are a lack of comprehensive tutorials.</p>

<p>Take the <a href='http://developer.android.com/guide/tutorials/notepad/index.html'>Notepad tutorial</a> for example, for every exercise you have to start from an archive of what the project should look like. It is impossible to follow the tutorial through without starting all over again with these archives. There is even an &#8221;<strong>Extra Credit</strong>&#8221; section. I&#8217;m not even going to comment on that one.</p>

<p>Really, it feels just like i&#8217;m <strong>copying and pasting</strong> code. i.e. not <strong>learning</strong> anything. <h3>To Conclude</h3> So safe to say, i&#8217;m <strong>not going to make an Android app</strong> anytime in the near future.</p>

<p>Now i realise why Google is offering cash prices for making android apps: The SDK is so horrible, you&#8217;ll need all the money to pay for the therapy you&#8217;ll need after you finish your app.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>The Wonders of iPhone Camera Apps</title>

		<link>http://www.cuppadev.co.uk/the-wonders-of-iphone-camera-apps/</link>
		<comments>http://www.cuppadev.co.uk/the-wonders-of-iphone-camera-apps/#comments</comments>
		<pubDate>Fri, 14 Aug 2009 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=489</guid>
		<description><![CDATA[<img alt='IMG_0479' class='alignnone size-full wp-image-491' height='320' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/08/IMG_0479.jpg' title='IMG_0479' width='480' /> <p>Those of you who happen to follow me on Twitter might have heard a while back that i tried releasing a camera app for the iPhone, which simply allowed you to overlay arbitrary images as guides over the camera.</p> <p>Unfortunately it was rejected last month because of the following criteria:</p> <blockquote> "3.3.1 Applications may only use Documented APIs in the manner prescribed by Apple and must not use or call any private APIs." </blockquote> <p>Which to me was extremely annoying. Until you get rejected for something as arbitrary as this,...]]></description>
		<content:encoded><![CDATA[<img alt='IMG_0479' class='alignnone size-full wp-image-491' height='320' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/08/IMG_0479.jpg' title='IMG_0479' width='480' />
<p>Those of you who happen to follow me on Twitter might have heard a while back that i tried releasing a camera app for the iPhone, which simply allowed you to overlay arbitrary images as guides over the camera.</p>

<p>Unfortunately it was rejected last month because of the following criteria:</p>
<blockquote>
"3.3.1 Applications may only use Documented APIs in the manner prescribed by Apple and must not use or call any private APIs."  
</blockquote>
<p>Which to me was extremely annoying. Until you get rejected for something as arbitrary as this, i don&#8217;t think one truly understands how frustrating it can be to have a weeks worth of work flushed down the toilet.</p>

<p>My objections to this were as follows. All the API&#8217;s i used <strong>were documented</strong>. I simply made a UIImagePickerController, a UIView and overlaid it on top of the camera view. The only potentially problematic thing i did was to check for the presence of the TPCameraPushButton in the view hierarchy (again, a <strong>public api</strong>) to see when the overlay should vanish.</p>

<p>This check was written in such a way that if the class name of the camera button changed in a future release, the overlay would just stay visible all the time.</p>

<p>But no, apparently i didn&#8217;t use the API correctly <em>"in the manner prescribed by Apple"</em>. Thus no camera app was released.</p>

<p>Now i would have just left it there and waited until Apple made a nice API for me to properly overlay images over the camera (if ever), but what do i find posted on <a href='http://www.tuaw.com'>tuaw</a> today?</p>
<a href='http://www.tuaw.com/2009/08/13/camera-genius-for-iphone-updates-and-improves/'>"Camera Genius for iPhone updates and improves"</a>
<p>Yes, a camera app <strong>which overlays images on the camera</strong>. But not only that, it <strong>completely modifies the camera</strong>, and what&#8217;s more, it was both <strong>updated and approved</strong> well before and after my application.</p>

<p>(Note that i did not know about this particular camera app before i made mine. In addition it doesn&#8217;t appear to allow custom overlay images, one of the features of my app)</p>

<p>I guess it&#8217;s ok to make a camera application which completely modifies the camera UI. But if you just overlay images and check to see if the camera button exists then no, that doesn&#8217;t utilise the API in the manner prescribed by Apple.</p>
<img alt='iCompetition' class='alignnone size-full wp-image-490' height='135' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/08/icompo.png' style='border:none;' title='icompo' width='370' />
<p>So i have a challenge for you iPhone Developers out there. I have <strong>released the sourcecode</strong> to my ill-fated camera app, OverTheCam, under the GPL. Your mission, should you choose to accept it is to <strong>get it approved</strong> by Apple.</p>

<p>I&#8217;m going to award points based on :</p>
<ul>
	<li>How much of the app you need to change to get it approved. </li>
	<li>How many "Camera Genius" UI enhancements you can get away with</li>
	<li>How long it takes to get approved</li>
        <li>The alternate name you pick</li>
</ul>
<p>Additionally entries designed for any version of the OS later than 3.0.1 will not be counted. I&#8217;d also like to point out that you&#8217;ll also need to change the name of the application when submitting, for obvious reasons.</p>

<p>So what are you waiting for? <a href='http://github.com/jamesu/overthecam/tree/master'>Grab the code here on github and get submitting!</a></p>]]></content:encoded>
	</item>
	
	<item>
		<title>Moved to gandi.net</title>

		<link>http://www.cuppadev.co.uk/moved-to-gandi-net/</link>
		<comments>http://www.cuppadev.co.uk/moved-to-gandi-net/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=487</guid>
		<description><![CDATA[<p>For a few years now, i&#8217;ve been hosting this site on <a href='http://www.dreamhost.com'>Dreamhost</a>. Despite the subpar performance, 90% of the time the site was up churning out requests, which for me worked out great.</p> <p>Still, there&#8217;s something about shared hosting that makes me cringe, so i&#8217;ve been meaning to move to a VPS (Virtual Private Server) for quite some time now. After much consideration, i&#8217;ve decided to go with <a href='http://www.gandi.net'>gandi.net</a>. The reason? I&#8217;ve tried it before and they offer a fair price for what they offer: a single 256mb &#8220;slice&#8221; for $16/month, scalable up to 16 slices.</p> <p>It may...]]></description>
		<content:encoded><![CDATA[<p>For a few years now, i&#8217;ve been hosting this site on <a href='http://www.dreamhost.com'>Dreamhost</a>. Despite the subpar performance, 90% of the time the site was up churning out requests, which for me worked out great.</p>

<p>Still, there&#8217;s something about shared hosting that makes me cringe, so i&#8217;ve been meaning to move to a VPS (Virtual Private Server) for quite some time now. After much consideration, i&#8217;ve decided to go with <a href='http://www.gandi.net'>gandi.net</a>. The reason? I&#8217;ve tried it before and they offer a fair price for what they offer: a single 256mb &#8220;slice&#8221; for $16/month, scalable up to 16 slices.</p>

<p>It may be a little bit more expensive than Dreamhost, but in the long run, i reckon it will pay back in terms of uptime and expandability.</p>

<p>So goodbye Dreamhost, hello Gandi!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>RailsCollab isn't Dead</title>

		<link>http://www.cuppadev.co.uk/railscollab-isnt-dead/</link>
		<comments>http://www.cuppadev.co.uk/railscollab-isnt-dead/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=422</guid>
		<description><![CDATA[<p>For those of you interested in web-based project management tools, you might have noticed i&#8217;ve not really been maintaining <a href='http://github.com/jamesu/railscollab/tree/master'>RailsCollab</a> for quite a few months now. Why? well because i really wanted to concentrate on other things, such as making <a href='http://www.jamesu.net/apps'>cool iPhone apps</a> and the usual contracts.</p> <p>(Plus to be honest i wasn&#8217;t really using it myself)</p> <p>Still, since its open source other people were free to use and modify it for their own needs. I was pleased to see that there has been a healthy level of forking according to <a href='http://github.com/jamesu/railscollab/network'>github's network graph</a>.</p> <a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/07/fork_graph_rc.png'><img alt='fork_graph_rc'...]]></description>
		<content:encoded><![CDATA[<p>For those of you interested in web-based project management tools, you might have noticed i&#8217;ve not really been maintaining <a href='http://github.com/jamesu/railscollab/tree/master'>RailsCollab</a> for quite a few months now. Why? well because i really wanted to concentrate on other things, such as making <a href='http://www.jamesu.net/apps'>cool iPhone apps</a> and the usual contracts.</p>

<p>(Plus to be honest i wasn&#8217;t really using it myself)</p>

<p>Still, since its open source other people were free to use and modify it for their own needs. I was pleased to see that there has been a healthy level of forking according to <a href='http://github.com/jamesu/railscollab/network'>github's network graph</a>.</p>
<a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/07/fork_graph_rc.png'><img alt='fork_graph_rc' class='alignnone size-thumbnail wp-image-423' height='105' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/07/fork_graph_rc-300x105.png' title='fork_graph_rc' width='300' /></a>
<p>Feature-wise, one fork made by <a href='http://github.com/scambra/railscollab/'>scambra</a> has even implemented a fully fledged wiki.</p>
<img alt='wiki_tab' class='alignnone size-full wp-image-424' height='32' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/07/wiki_tab.png' title='wiki_tab' width='222' />
<p>I&#8217;ve also seen partial localisation&#8217;s implemented for German and Simplified Chinese. So safe to say, i&#8217;m very impressed that despite my lack of updates, RailsCollab is still going strong - all thanks to its growing community! <h3>Now for my input...</h3> Projects like RailsCollab are hardly one-way streets. One has to give back as well as receive contributions.</p>

<p>So i&#8217;m pleased to announce that as well as merging the wiki and language updates into the main RailsCollab tree, i&#8217;ve also merged in my own updates which convert the Message, Comment, and File controllers into RESTful resource controllers.</p>

<p>Simply put, this means that you can now manipulate messages, comments, and files as XML. e.g.:</p>
<strong>/project/1/messages/1.xml</strong><pre><code>
&lt;message&gt;
  &lt;additional-text/&gt;
  &lt;attached-files-count type="integer"&gt;0&lt;/attached-files-count&gt;
  &lt;category-id type="integer"&gt;1&lt;/category-id&gt;
  &lt;comments-count type="integer"&gt;2&lt;/comments-count&gt;
  &lt;comments-enabled type="boolean"&gt;true&lt;/comments-enabled&gt;
  &lt;created-by-id type="integer"&gt;1&lt;/created-by-id&gt;
  &lt;created-on type="datetime"&gt;2009-07-16T19:35:00Z&lt;/created-on&gt;
  &lt;id type="integer"&gt;1&lt;/id&gt;
  &lt;is-important type="boolean"&gt;false&lt;/is-important&gt;
  &lt;is-private type="boolean"&gt;false&lt;/is-private&gt;
  &lt;milestone-id type="integer"&gt;0&lt;/milestone-id&gt;
  &lt;project-id type="integer"&gt;1&lt;/project-id&gt;
  &lt;text&gt;It's a *test*!&lt;/text&gt;
  &lt;title&gt;Test message!&lt;/title&gt;
  &lt;updated-by-id type="integer"&gt;1&lt;/updated-by-id&gt;
  &lt;updated-on type="datetime"&gt;2009-07-16T19:35:16Z&lt;/updated-on&gt;
&lt;/message&gt;
</code></pre><strong>/project/1/messages/1/comments.xml</strong><pre><code>
&lt;comments type="array"&gt;
  &lt;comment&gt;
    &lt;attached-files-count type="integer"&gt;0&lt;/attached-files-count&gt;
    &lt;author-name nil="true"/&gt;
    &lt;created-by-id type="integer"&gt;1&lt;/created-by-id&gt;
    &lt;created-on type="datetime"&gt;2009-07-17T20:34:12Z&lt;/created-on&gt;
    &lt;id type="integer"&gt;5&lt;/id&gt;
    &lt;is-anonymous type="boolean"&gt;false&lt;/is-anonymous&gt;
    &lt;is-private type="boolean"&gt;true&lt;/is-private&gt;
    &lt;text&gt;Test REST comment - edited&lt;/text&gt;
  &lt;/comment&gt;
&lt;/comments&gt;
</code></pre><strong>/project/1/files.xml</strong><pre><code>
&lt;files type="array"&gt;
  &lt;file&gt;
    &lt;comments-count type="integer"&gt;0&lt;/comments-count&gt;
    &lt;comments-enabled type="boolean"&gt;true&lt;/comments-enabled&gt;
    &lt;created-by-id type="integer"&gt;1&lt;/created-by-id&gt;
    &lt;created-on type="datetime"&gt;2009-07-18T13:22:20Z&lt;/created-on&gt;
    &lt;filename&gt;kitten-logo.png&lt;/filename&gt;
    &lt;id type="integer"&gt;9&lt;/id&gt;
    &lt;is-important type="boolean"&gt;false&lt;/is-important&gt;
    &lt;is-locked type="boolean"&gt;false&lt;/is-locked&gt;
    &lt;is-private type="boolean"&gt;false&lt;/is-private&gt;
    &lt;updated-on type="datetime"&gt;2009-07-18T13:34:50Z&lt;/updated-on&gt;
  &lt;/file&gt;
&lt;/files&gt;
</code></pre>
<p>So what are you waiting for? fork it, use it, <strong>enjoy</strong>!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>New iPhone Puzzle Game: VidSplit</title>

		<link>http://www.cuppadev.co.uk/new-iphone-puzzle-game-vidsplit/</link>
		<comments>http://www.cuppadev.co.uk/new-iphone-puzzle-game-vidsplit/#comments</comments>
		<pubDate>Tue, 26 May 2009 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=419</guid>
		<description><![CDATA[<p>Just thought i&#8217;d let all you devoted readers know, i just released my second iPhone app on iTunes, <a href='http://itunes.com/apps/vidsplit'>vidsplit</a>.</p> <img alt='vidsplit' class='alignnone size-full wp-image-420' height='320' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/05/vidsplit.png' title='vidsplit' width='480' /> <p>vidsplit is a simple picture puzzle game with an added twist: instead of a picture, you have to piece together a <strong>full-motion</strong> video. With a grand total of two difficulty settings and 3 puzzles, it should keep pretty much any puzzle enthusiast entertained for hours.</p> <p>On the technical side of things, vidsplit is basically a really souped up fork of <a href='http://itunes.com/apps/anim8gif'>anim8gif</a>. Instead of animated gifs however, i&#8217;m using far...]]></description>
		<content:encoded><![CDATA[<p>Just thought i&#8217;d let all you devoted readers know, i just released my second iPhone app on iTunes, <a href='http://itunes.com/apps/vidsplit'>vidsplit</a>.</p>
<img alt='vidsplit' class='alignnone size-full wp-image-420' height='320' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/05/vidsplit.png' title='vidsplit' width='480' />
<p>vidsplit is a simple picture puzzle game with an added twist: instead of a picture, you have to piece together a <strong>full-motion</strong> video. With a grand total of two difficulty settings and 3 puzzles, it should keep pretty much any puzzle enthusiast entertained for hours.</p>

<p>On the technical side of things, vidsplit is basically a really souped up fork of <a href='http://itunes.com/apps/anim8gif'>anim8gif</a>. Instead of animated gifs however, i&#8217;m using far higher quality <strong>PVR compressed</strong> videos.</p>

<p>Why PVR? Well, it really is the only thing you can use to get <strong>smooth video playback</strong>, apart from the hardware mpeg decoding chips which sadly aren&#8217;t accessible using the SDK. All <strong>other methods</strong> and texture formats are far <strong>too slow</strong> to get any acceptable playback speed.</p>

<p>For the curious, you might also be interested to know the video frames are basically 256x256 pixels in size, stretched to the dimensions of the screen. Any bigger and the video files would balloon in size. Any smaller and the video would look like complete mush, so it&#8217;s pretty much an acceptable sweet spot in terms of quality.</p>

<p>The decoder is pretty simple. Every frame, a PVR texture is read from the video file (basically concatenated PVR textures) and uploaded as an OpenGLES texture. Ad-infimum. It really couldn&#8217;t be any simpler than that!</p>

<p>As for the actual graphical interface, i&#8217;m using a custom solution based on my <a href='http://github.com/jamesu/kitten/tree/master'>kitten</a> game engine.</p>
<h3>To conclude</h3>
<p>So what are you waiting for, why not <a href='http://itunes.com/apps/vidsplit'>buy it from itunes</a>? :)</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Playing Animated GIFs on the iPhone</title>

		<link>http://www.cuppadev.co.uk/playing-animated-gifs-on-the-iphone/</link>
		<comments>http://www.cuppadev.co.uk/playing-animated-gifs-on-the-iphone/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=412</guid>
		<description><![CDATA[<p>Following on from my <a href='http://www.cuppadev.co.uk/iphone/animated-images-on-the-iphone-sans-memory-leaks/'>Animated images on the iPhone</a> post, i thought i&#8217;d take things a step further.</p> <p>To re-cap, i pretty much summarised the available options for playing back simple animations on the iphone in this nice table:</p> <table style='border: 1px solid #afafaf; color: #000000; background: #ffffff'> <thead> <tr><th><strong>Method</strong></th><th><strong>Problem</strong></th></tr> </thead> <tbody> <tr><td>Use UIImageView</td><td>It doesn't scale</td></tr> <tr><td>Re-draw a UIView every frame</td><td>Far too slow</td></tr> <tr><td>Use GLES</td><td>Beyond the scope of the last article, <strong>but not this one</strong>!</td></tr> <tr><td>Transform a clipped UIView each frame</td><td>We did that last time</td></tr> </tbody> </table> <p>To take things further, OpenGLES needs to be used. Specifically, you need...]]></description>
		<content:encoded><![CDATA[<p>Following on from my <a href='http://www.cuppadev.co.uk/iphone/animated-images-on-the-iphone-sans-memory-leaks/'>Animated images on the iPhone</a> post, i thought i&#8217;d take things a step further.</p>

<p>To re-cap, i pretty much summarised the available options for playing back simple animations on the iphone in this nice table:</p>
<table style='border: 1px solid #afafaf; color: #000000; background: #ffffff'>
<thead>
<tr><th><strong>Method</strong></th><th><strong>Problem</strong></th></tr>
</thead>
<tbody>
<tr><td>Use UIImageView</td><td>It doesn't scale</td></tr>
<tr><td>Re-draw a UIView every frame</td><td>Far too slow</td></tr>
<tr><td>Use GLES</td><td>Beyond the scope of the last article, <strong>but not this one</strong>!</td></tr>
<tr><td>Transform a clipped UIView each frame</td><td>We did that last time</td></tr>
</tbody>
</table>
<p>To take things further, OpenGLES needs to be used. Specifically, you need to upload and draw a texture for every frame of your animation.</p>

<p>Now while this sounds like a great idea, there is a slight problem: uploading textures on the iPhone is hideously slow. Excluding the requirements of a video decoder, you only have enough time per frame to be able to playback a small stop motion video in RGB format.</p>

<p>All is not lost though. The iPhone supports two rather interesting texture formats: <strong>GL_COMPRESSED_RGB_PVRTC_*</strong> which is the native format, and <strong>GL_PALETTE*</strong> which is, as the name implies is a texture with a palette.</p>

<p>The fastest format to upload is PVR, but unfortunately there aren&#8217;t many native video codecs or animation formats about that decode to PVR format. Which leaves us with the palette format, which is just about fast enough to playback something more substantial&#8230;</p>

<p>Now which animation format uses a palette and is widely supported? <strong>Animated gif</strong>!</p>

<p>So to cut a long story short, i ended up writing a fairly elaborate library to decode and playback animated gifs on the iPhone, all in realtime.</p>

<p>Provided the gif is not gigantic (since the bigger the gif, the slower the decode + upload), it&#8217;s actually quite useable.</p>
<a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/03/picture-1.png'><img alt='anim8gif' class='alignnone size-thumbnail wp-image-413' height='200' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/03/picture-1-139x200.png' title='anim8gif' width='139' /></a>
<p>In fact, as a proof of concept i ended up writing an app using this library to playback animated gifs from any website in fullscreen (similar to the youtube app). Feel free to check it out - <a href='http://www.itunes.com/app/anim8gif'>anim8gif</a>.</p>
<h3>The code</h3>
<p>The code for this gif animation library, <strong>glgif</strong>, is <a href='http://github.com/jamesu/glgif/tree/master'>located on github</a>. As always, feel free to fork!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Double Entry Accounting with Invoicing in Rails</title>

		<link>http://www.cuppadev.co.uk/double-entry-accounting-with-invoicing-in-rails/</link>
		<comments>http://www.cuppadev.co.uk/double-entry-accounting-with-invoicing-in-rails/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=321</guid>
		<description><![CDATA[<p>You may remember a little post i made ages ago about <a href='http://www.cuppadev.co.uk/oldbrew/double-entry-accounting-in-rails/'>Double Entry Accounting in Rails</a>, in which i went over what one needed in order to make a simple double entry accounting system within the confines of the Ruby on Rails web development framework.</p> <p>After a few requests by readers, i have decided to write the sequel. Double Entry Accounting <strong>with Invoicing</strong> in Rails.</p> <h3>To recap...</h3> <p>Last time i identified the following core tables you needed in your database:</p> <ul> <li><em>Account</em> (has many Postings)</li> <li><em>Asset</em> Type (e.g. £, $, monkeys)</li> <li><em>Batch</em> (has many Journals, links them into a...]]></description>
		<content:encoded><![CDATA[<p>You may remember a little post i made ages ago about <a href='http://www.cuppadev.co.uk/oldbrew/double-entry-accounting-in-rails/'>Double Entry Accounting in Rails</a>, in which i went over what one needed in order to make a simple double entry accounting system within the confines of the Ruby on Rails web development framework.</p>

<p>After a few requests by readers, i have decided to write the sequel. Double Entry Accounting <strong>with Invoicing</strong> in Rails.</p>
<h3>To recap...</h3>
<p>Last time i identified the following core tables you needed in your database:</p>

<ul>
<li><em>Account</em> (has many Postings)</li>

<li><em>Asset</em> Type (e.g. £, $, monkeys)</li>

<li><em>Batch</em> (has many Journals, links them into a group of transactions - though not really needed)</li>

<li><em>Journal</em> (has many Postings, links them into a <strong>transaction</strong>)</li>

<li><em>Posting</em> (associates with Account, Journal, and Asset Type)</li>
</ul>

<p>Though i failed to elaborate on what you really needed to store in these tables. In truth, it can be as complicated or as simple as you&#8217;d like. No need for Batches? Then don&#8217;t include them.</p>

<p>As long as you at least store amounts in Posting&#8217;s, and practice the <a href='http://en.wikipedia.org/wiki/Double-entry_bookkeeping_system'>art of double entry accounting</a>, you should be fine.</p>

<p>The next major point of note was how does one calculate the balances in the accounts? Well it turned out the solution was rather simple:</p>

<pre><code>credit_amount = postings.sum(:value, :conditions =&amp;gt; &quot;amount &amp;lt; 0&quot;)
debit_amount = postings.sum(:value, :conditions =&amp;gt; &quot;amount &amp;gt; 0&quot;)</code></pre>

<p>Coupled in with the balances were the amounts in the Postings, which had to be flipped depending on the type of account they resided in:</p>

<pre><code>def real_amount
  return [:asset, :expense].include?(self.account.account_type) ? self.value : -self.value
end

def real_amount=(val)
  self.value = [:asset, :expense].include?(self.account.account_type) ? val : -val
end</code></pre>

<p>In simpler terms: if an account is an asset or expense account, a positive value = a positive amount. Otherwise, a positive value = a negative amount. Vice versa.</p>
<h3>So how do we factor invoicing into this?</h3>
<p>There are two ways in which invoicing can be linked into a double entry accounting system: <ol>
  <li>Link the <strong>payment</strong> of each invoice to transactions in the system</li>
  <li>Link the <strong>amount owed</strong> by each client for each invoice to transactions in the system</li>
</ol></p>

<p>Realistically though, #1 is a fairly stupid idea as in the real world, clients don&#8217;t always pay on time. Or with the correct amount or order. Not only that, they can also pay off multiple invoices at once!</p>

<p>Which brings us to #2 - linking the amount owed by each client for each invoice into the system.</p>

<p>How do we do this? Well to summarise: <ul>
  <li>Have a <strong>revenue account</strong> which tracks how much you make.</li>
  <li>Have a <strong>checking account</strong> which tracks what is in the bank.</li>
  <li>Make an <strong>asset account</strong> for each client.</li>
  <li>When you make out an invoice, record a <strong>transaction</strong> which transfers the total amount of the invoice from your <strong>revenue account</strong> into the <strong>client account</strong>.</li>
  <li>Link any <strong>transaction</strong>(s) generated by the invoice to the invoice (so you can revert them later if required)</li>
  <li> When the client pays, record a <strong>transaction</strong> which transfers the paid amount from the <strong>client account</strong> into your <strong>checking account</strong>.</li>
</ul></p>

<p>Which might look like this in the system:</p>
<table style='border: 1px solid #000000'>
<tr>
<th colspan='2' style='background:#000000;color:#ffffff'>Account</th>
<th style='background:#000000;color:#ffffff'>Debit</th>
<th style='background:#000000;color:#ffffff'>Credit</th>
</tr>
<tr>
<td colspan='2'><strong>Checking Accounts</strong></td>
<td />
<td />
</tr>
<tr>
<td />
<td>Bank</td>
<td>100</td>
<td>0</td>
</tr>
<tr>
<td colspan='2'><strong>Invoice Accounts</strong></td>
<td />
<td />
</tr>
<tr>
<td />
<td>Microsoft</td>
<td>50</td>
<td>0</td>
</tr>
<tr>
<td />
<td>Apple</td>
<td>50</td>
<td>0</td>
</tr>
<tr>
<td colspan='2'><strong>Revenue Accounts</strong></td>
<td />
<td />
</tr>
<tr>
<td />
<td>Revenue</td>
<td>0</td>
<td>200</td>
</tr>
</table>
<p>So&#8230;</p>
<ul>
<li>For tax purposes, your revenue account will at least sum up to the total amount in all of your invoices.</li>
<li>If the client's account has a positive balance, they owe you money for any one of your invoices.</li>
<li>If the client's account has a negative balance, they've obviously overpaid you. So go party!!</li>
</ul>
<p>&#8230; which more or less concludes this article. Happy accounting!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Animated images on the iPhone - sans memory leaks!</title>

		<link>http://www.cuppadev.co.uk/animated-images-on-the-iphone-sans-memory-leaks/</link>
		<comments>http://www.cuppadev.co.uk/animated-images-on-the-iphone-sans-memory-leaks/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=367</guid>
		<description><![CDATA[<p>For those of you who have developed on the iPhone, you may have cringed at the prospect of having an animated image in your app, due to the flaky operation of the <strong>UIImageView</strong> which is the de-facto method of making a simple image animation.</p> <p>For small images and animations, UIImageView works well. However, when you get to bigger and longer animations, it simply <strong>doesn't scale</strong>. You might be fooled by the simulator, but on the real device your images will load very slowly before succumbing to the limited memory available.</p> <p>Fortunately, there are other methods in which to playback and...]]></description>
		<content:encoded><![CDATA[<p>For those of you who have developed on the iPhone, you may have cringed at the prospect of having an animated image in your app, due to the flaky operation of the <strong>UIImageView</strong> which is the de-facto method of making a simple image animation.</p>

<p>For small images and animations, UIImageView works well. However, when you get to bigger and longer animations, it simply <strong>doesn't scale</strong>. You might be fooled by the simulator, but on the real device your images will load very slowly before succumbing to the limited memory available.</p>

<p>Fortunately, there are other methods in which to playback and animated image. The first and perhaps the best method would be to implement everything in GLES. The second, which will be described here might be easier if you don&#8217;t want to setup GLES, considering it uses standard UIKit.</p>
<h3>To start with</h3><img alt='The Challenge' class='size-full wp-image-372' height='66' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/02/animated.gif' width='96' />
<p>Here&#8217;s the theory: <strong>UIImageView sucks</strong>, so we need another method in which to animate images.</p>
<table style='border: 1px solid #afafaf; color: #000000; background: #ffffff'>
<thead>
<tr><th><strong>Method</strong></th><th><strong>Problem</strong></th></tr>
</thead>
<tbody>
<tr><td>Use UIImageView</td><td>It doesn't scale</td></tr>
<tr><td>Re-draw a UIView every frame</td><td>Far too slow</td></tr>
<tr><td>Use GLES</td><td>Beyond the scope of this article</td></tr>
<tr><td>Transform a clipped UIView each frame</td><td>None, perfect!</td></tr>
</tbody>
</table>
<p>As you can see, there are only two realistic methods in which to animate our image: either <strong>use GLES</strong>, or <strong>transform a view</strong> around the screen.</p>

<p>Since i don&#8217;t want to be messing around with GLES right now, i&#8217;ll tackle the UIView, or flip-book approach.</p>
<img alt='Illustration of Concept' class='alignnone size-thumbnail wp-image-374' height='199' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/02/illus-anim-243x199.png' title='Illustration of Concept' width='243' />
<p>A flip-book can be made either by putting an image in a <strong>UIScrollView</strong> and scrolling through it, or by making a custom clipped <strong>UIView</strong> with the image inserted as a subview.</p>

<p>(The latter approach which i prefer as it is a bit cleaner)</p>
<h3>The code put simply</h3>
<p>To start off with, your master view needs to be set to clip its subviews on init. i.e.:</p>

<pre><code>self.clipsToBounds = YES;</code></pre>

<p>And the subview, which should be a UIView which basically needs to draw a big image containing all the frames, needs to have user interaction disabled. i.e.:</p>

<pre><code>// MYAnimationViewSlide code

- (void)setImage:(UIImage*)aValue {
  [image release];
  image = [aValue retain];

  // Resize to fit
  CGSize sz = image.size;
  self.frame = CGRectMake(0, 0, sz.width, sz.height);

  [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect {
  // ...
  // Just draw the image!
  [image drawAtPoint:CGPointMake(0, 0)];

  // No more need for the image
  [image release];
  image = nil;
  // ...
}

// in init...
  self.userInteractionEnabled = NO;</code></pre>

<p>Then all you need to do is move your slide around in your view by setting the .transform property, i.e.:</p>

<pre><code>// MYAnimationView code

// slide size == child view size
CGSize slideSz = slide.bounds.size;
// frame size == root view size
CGSize viewSz = self.bounds.size;

// Calculate x,y position for the frame
// (assuming your frames are packed in a block rather than a strip)
int framesPerRow = floor(slideSz.width / viewSz.width);
int x = currentFrame % framesPerRow;
int y = currentFrame / framesPerRow;

slide.transform = CGAffineTransformMakeTranslation(-viewSz.width*x, 
                                                   -viewSz.height*y);</code></pre>

<p>While tied to an NSTimer:</p>

<pre><code>// MYAnimationView code

advanceTime = (1.0 / 25.0);
animTimer = [NSTimer scheduledTimerWithTimeInterval:advanceTime
                     target:self 
                     selector:@selector(animateTimer:) 
                     userInfo:nil repeats:YES];

// ...

- (void)animateTimer:(NSTimer*)timer
{
  NSTimeInterval timeInterval=timer.timeInterval;
  NSTimeInterval currentTime=[NSDate timeIntervalSinceReferenceDate];

  if (lastTime != 0) {
    double delta = (currentTime - lastTime) / timeInterval;

    // advance by at least 1 frame, at most frames in delta
    if (delta &lt; 1)
      self.currentFrame += 1;
    else
      self.currentFrame += (int)delta;
  }

  lastTime = currentTime;
}</code></pre>

<p>It&#8217;s as simple as that!</p>

<p>(unless your slides exceed <strong>1024x1024</strong>, in which case you need to use more than one slide. i&#8217;ll let you figure that one out)</p>
<h3>The Code</h3>
<p>For those of you who are interested in the code for this flip-book, i have <a href='http://gist.github.com/70751'>pasted a gist on github</a>. As always, feel free to fork!</p>

<p>And in case you want an example image, here&#8217;s a set of frames for a 50 frame, 96x66 animation.</p>
<a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/02/anim.png'><img alt='anim' class='alignnone size-thumbnail wp-image-394' height='103' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/02/anim-300x103.png' title='anim' width='300' /></a>]]></content:encoded>
	</item>
	
	<item>
		<title>Making a Real Calendar in Rails</title>

		<link>http://www.cuppadev.co.uk/making-a-real-calendar-in-rails/</link>
		<comments>http://www.cuppadev.co.uk/making-a-real-calendar-in-rails/#comments</comments>
		<pubDate>Wed, 28 Jan 2009 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=355</guid>
		<description><![CDATA[<p>For a while now, i have been looking at the various <a href='http://github.com/search?type=Repositories&amp;language=rb&amp;q=calendar&amp;repo=&amp;langOverride=&amp;x=0&amp;y=0&amp;start_value=1' target='_blank'>calendar helpers on Github</a>. One thing stands out over all of them: <strong>they all suck</strong>. <p style='text-align: center; '><a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/01/bad_calendar.gif' target='_blank'><img alt='bad_calendar' class='size-thumbnail wp-image-359 aligncenter' height='200' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/01/bad_calendar-261x200.gif' title='bad_calendar' width='261' /></a></p></p> <p>Why? well, they all implement the same basic concept - that is, they make a table containing rows for each week, and cells for each day, yielding in case the user wants to display anything other than a day number in the cell.</p> <p>This is fine if all you want to do is display single-day events, but...]]></description>
		<content:encoded><![CDATA[<p>For a while now, i have been looking at the various <a href='http://github.com/search?type=Repositories&amp;language=rb&amp;q=calendar&amp;repo=&amp;langOverride=&amp;x=0&amp;y=0&amp;start_value=1' target='_blank'>calendar helpers on Github</a>. One thing stands out over all of them: <strong>they all suck</strong>. <p style='text-align: center; '><a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/01/bad_calendar.gif' target='_blank'><img alt='bad_calendar' class='size-thumbnail wp-image-359 aligncenter' height='200' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/01/bad_calendar-261x200.gif' title='bad_calendar' width='261' /></a></p></p>

<p>Why? well, they all implement the same basic concept - that is, they make a table containing rows for each week, and cells for each day, yielding in case the user wants to display anything other than a day number in the cell.</p>

<p>This is fine if all you want to do is display single-day events, but if you want to <strong>go to the next level</strong> and display multiple &#8220;all day&#8221; events it is practically impossible as the events are constrained in their table cell. Instead, <strong>another approach</strong> is needed.</p>
<p style='text-align: center; '><a href='http://www.cuppadev.co.uk/wp-content/uploads/2009/01/good_calendar.gif' target='_blank'><img alt='good_calendar' class='size-thumbnail wp-image-358 aligncenter' height='200' src='http://www.cuppadev.co.uk/wp-content/uploads/2009/01/good_calendar-229x200.gif' title='good_calendar' width='229' /></a></p>
<p>The approach? Well, put simply the events are placed in a row below each set of day cells. Events which span more than 1 row are repeated, and a layout algorithm handles vertical placement.</p>

<p>Now rather than writing a whole post describing in agonising detail how to implement this approach, i thought i&#8217;d post a gist on github describing how to do it. <a href='http://gist.github.com/54116' target='_blank'>Read it here</a>. Any improvements? Feel free to fork. Comments? feel free to post below! <p style='text-align: center; '> </p></p>

<p><em>Update:</em> The great guy&#8217;s over at <a href='http://elevationblog.com/'>elevation</a> have <a href='http://dev.elevationblog.com/2009/7/23/event-calendar-rails-plugin/comments/1527#comment-1527'>turned this code into a plugin</a>. So if you don&#8217;t fancy implementing this all by yourself, just use the easy to install plugin. :)</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Surviving a Game Development Job Interview</title>

		<link>http://www.cuppadev.co.uk/surviving-a-game-development-job-interview/</link>
		<comments>http://www.cuppadev.co.uk/surviving-a-game-development-job-interview/#comments</comments>
		<pubDate>Tue, 30 Dec 2008 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=345</guid>
		<description><![CDATA[<p>The recent <del datetime='2009-02-04T22:35:29+00:00'>demise</del> downfall of <a href='http://www.1up.com/do/newsStory?cId=3172060'>Free Radical</a> brought back some fond memories of when i was trying to get a real programmer job in the Game Development industry. Sad to say, i didn&#8217;t make it - but then again after <a href='http://www.isotx.com/wordpress/?p=162'>second thoughts</a>, i kind of figured it wasn&#8217;t the <a href='http://en.wikipedia.org/wiki/Video_game_developer'>best career path</a> for me anyway.</p> <p>Still, i learnt quite a lot about what is expected from a game development job interview. And i thought i&#8217;d list my top 3 points here, which are general enough to apply to any game development profession: <h2>1) Bring a laptop...]]></description>
		<content:encoded><![CDATA[<p>The recent <del datetime='2009-02-04T22:35:29+00:00'>demise</del> downfall of <a href='http://www.1up.com/do/newsStory?cId=3172060'>Free Radical</a> brought back some fond memories of when i was trying to get a real programmer job in the Game Development industry. Sad to say, i didn&#8217;t make it - but then again after <a href='http://www.isotx.com/wordpress/?p=162'>second thoughts</a>, i kind of figured it wasn&#8217;t the <a href='http://en.wikipedia.org/wiki/Video_game_developer'>best career path</a> for me anyway.</p>

<p>Still, i learnt quite a lot about what is expected from a game development job interview. And i thought i&#8217;d list my top 3 points here, which are general enough to apply to any game development profession: <h2>1) Bring a laptop to show off how good you are</h2> This is perhaps the <strong>most important</strong> point. You cannot rely on thumb drives, cd&#8217;s, or the internet.</p>

<p>There is a high probability that your demos will not load properly on your interviewers systems. So be sure to show them on one that you know does work - yours.</p>

<p>In addition, the very fact that your demos are on your own hardware gives that extra inclination that you made them yourself. <h2>2) Brush up on common knowledge pertaining to your profession.</h2> Chances are that you will be given some form of test, either on paper or through meticulous quizzing. The aim of this is to weed out clueless candidates. Make sure you are not clueless. <h2>3) Have something to say, questions to ask.</h2> If you find that the interviewer is talking more than you are, then chances are they are more interested in themselves rather than who they should be interested in - you.</p>

<p>Have something well-formed to talk about. Don&#8217;t let the interviewer get carried away talking about some obscure technical concept.</p>

<p>The focus should be on you.</p>

<p>So after waffling on with the usual interview talk, your interviewer will usually ask &#8221;<em>Any more questions?</em>&#8221;. At this point, if you answer &#8221;<em>No</em>&#8221; then chances are you will fail the interview.</p>

<p>Why? Well, remember that there are two parties being interviewed. You and your interviewer. They are giving the reins over to you, in a sense.</p>

<p>So now is your last chance to stand out from the crowd (if you haven&#8217;t done so already). If you do not take it, then there will be little to distinguish yourself from the rest of the candidates. <h2>To conclude</h2> Anyone else have any more suggestions? Feel free to comment below!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>C to ActionScript via Adobe Alchemy</title>

		<link>http://www.cuppadev.co.uk/c-to-actionscript-via-adobe-alchemy/</link>
		<comments>http://www.cuppadev.co.uk/c-to-actionscript-via-adobe-alchemy/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=327</guid>
		<description><![CDATA[<p>Recently <a href='http://labs.adobe.com/technologies/alchemy/'>Adobe's Alchemy</a> was released to the public for testing. It claims to be a tool which can &#8220;compile C and C++ code that is targeted to run on the open source ActionScript Virtual Machine (AVM2)&#8221;.</p> <p>In English, that means you can take C and C++ applications and <strong>run them in Flash 10</strong>.</p> <p>Since i am always interested in the next big thing, i though i&#8217;d check it out by porting something interesting over. Previously i managed to <a href='http://www.cuppadev.co.uk/oldbrew/scumm-in-javascript/'>rewrite a SCUMM interpreter</a> from C to HaXe for Flash 9. So naturally, to form a good comparison i decided...]]></description>
		<content:encoded><![CDATA[<p>Recently <a href='http://labs.adobe.com/technologies/alchemy/'>Adobe's Alchemy</a> was released to the public for testing. It claims to be a tool which can &#8220;compile C and C++ code that is targeted to run on the open source ActionScript Virtual Machine (AVM2)&#8221;.</p>

<p>In English, that means you can take C and C++ applications and <strong>run them in Flash 10</strong>.</p>

<p>Since i am always interested in the next big thing, i though i&#8217;d check it out by porting something interesting over. Previously i managed to <a href='http://www.cuppadev.co.uk/oldbrew/scumm-in-javascript/'>rewrite a SCUMM interpreter</a> from C to HaXe for Flash 9. So naturally, to form a good comparison i decided to compile this interpreter using Adobe&#8217;s Alchemy instead. <h3>What went right</h3> <p style='text-align:left'><a href='http://www.cuppadev.co.uk/wp-content/uploads/2008/11/scvm-shot.png'><img alt='' class='alignleft size-thumbnail wp-image-332' height='200' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/11/scvm-shot-265x200.png' title='scvm-shot' width='265' /></a></p></p>

<p>Well, i managed to get it ported, using a front-end written in AS3, and the back-end compiled to a <strong>swc</strong> via Alchemy. Above you can see a screen shot of the version written in C (the haXe version for comparison <a href='http://www.cuppadev.co.uk/wp-content/uploads/2008/11/hiscumm-shot.png'>here</a>). Compared to the haXe implementation, the C version is much more <strong>feature complete</strong>.</p>

<p>It should also be noted that it took me only 2 days to get the Adobe Alchemy version to work properly, vs several weeks to get the HaXe version <strong>barely functional</strong>. <h3>What went wrong</h3> While Adobe Alchemy is cool, it was a nightmare to work with. For starters, compiling in C++ was broken (as the new operator didn&#8217;t work), so i could only compile programs written in C. This obviously meant no <a href='http://www.scummvm.org'>ScummVM</a> port, which would have been far more featureful.</p>

<p>It also meant that i had to put up with the full quirkiness of the horrible Alchemy API. For example, this grabs the current time:</p>

<pre><code>static unsigned sdl_scvm_get_time(scvm_backend_sdl_t* be) {
  AS3_Val ns;
  AS3_Val func;
  AS3_Val ares;
  AS3_Val und = AS3_Undefined();
  AS3_Val params = AS3_Array(&quot;&quot;);
  int res;

  ns = AS3_String(&quot;flash.utils&quot;);
  func = AS3_NSGetS(ns, &quot;getTimer&quot;);
  ares = AS3_Call(func, und, params);
  res = AS3_IntValue(ares);

  AS3_Release(ares);
  AS3_Release(ns);
  AS3_Release(func);
  AS3_Release(und);
  AS3_Release(params);

  return res;
}</code></pre>

<p>Ok, maybe i am exaggerating a bit here, but it seems that almost every function requires an <em>AS3_Val</em>, which you need to release. And it gets really annoying when you have to keep remembering to explicitly release everything you use. Hasn&#8217;t anyone at Adobe heard of <a href='http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Concepts/AutoreleasePools.html'>autorelease pools</a>?</p>

<p>Another thing is i could not find a proper way of debugging the C code. I had to resort to printing out values and trying to decipher the cryptic error messages which don&#8217;t really help me figure out the real problem.</p>

<pre><code>Error: Error #1502: A script has executed for longer than the default timeout period of 15 seconds.
        at ()[45593.achacks.as:3340]
        at ()[45593.achacks.as:3902]
        at ScummTest/initEngine()
        at ScummTest$/process_loadQueue()
        at ScummTest$/swfLoaded()
        at flash.events::EventDispatcher/dispatchEventFunction()
        at flash.events::EventDispatcher/dispatchEvent()
        at flash.net::URLLoader/onComplete()</code></pre>

<p>It would also have helped if there was proper documentation. True, there were a few examples, and you can figure out a few things from looking at the headers, but <strong>source code is not documentation</strong>.</p>

<p>And finally, even if you ignore the failings of the API and documentation, you still have to contend with the slow performance. In my example, the SCUMM interpreter was notably slower than its natively compiled counterpart, especially when it printed all of its debugging statements to the trace log. And even when it wasn&#8217;t printing anything out, it still took a long time doing seemingly nothing. <h3>To conclude</h3> To be fair, Adobe Alchemy is still &#8220;pre-release&#8221; software, so i have no doubt it will improve over the coming months.</p>

<p>In addition Adobe specifically mention that &#8220;Alchemy is primarily intended to be used with C/C++ libraries that have few operating system dependencies&#8221; and &#8220;is not intended for general development of SWF applications using C/C++&#8221;.</p>

<p>So i don&#8217;t think i will be making a habit of porting C/C++ applications to Flash using Alchemy.</p>

<p>Ok, libraries perhaps. But applications?</p>

<p>I really think it is better to write as much as you can in ActionScript or HaXe. It isn&#8217;t like in <a href='http://en.wikipedia.org/wiki/.NET_Framework'>.NET</a> where you can access objects and classes in the runtime via a transparent interface. You have to <strong>explicitly use the AS3 interface</strong> in order to manipulate native ActionScript objects.</p>

<p>Still, i look forward to see what becomes of Alchemy.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>What's New in Rucksack</title>

		<link>http://www.cuppadev.co.uk/whats-new-in-rucksack/</link>
		<comments>http://www.cuppadev.co.uk/whats-new-in-rucksack/#comments</comments>
		<pubDate>Mon, 27 Oct 2008 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=315</guid>
		<description><![CDATA[<p>A while ago, i posted a little piece about my <a href='http://www.cuppadev.co.uk/uncategorized/cloning-backpack/'>Backpack-inspired organisation tool</a>, Rucksack. At the time, i only just got the basics working, and it was nowhere near &#8220;production ready&#8221;.</p> <p>Now, it still isn&#8217;t really &#8220;production ready&#8221;, but it has drastically improved these past few months. In August, it started out looking like:</p> <p style='text-align:left'><a href='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/picture-11.png'><img alt='' class='alignnone size-thumbnail wp-image-276' height='138' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/picture-11-300x132.png' title='rck_overview' width='300' /></a></p> <p>And now it looks like this: <p style='text-align:left'><a href='http://www.cuppadev.co.uk/wp-content/uploads/2008/10/rck-new.png'><img alt='' class='alignnone size-thumbnail wp-image-316' height='156' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/10/rck-new-300x156.png' title='rck-new' width='300' /></a></p></p> <p>Which to say the least, is a big improvement.</p> <p>But &#8221;<em>What's new?</em>&#8221;, you may ask....]]></description>
		<content:encoded><![CDATA[<p>A while ago, i posted a little piece about my <a href='http://www.cuppadev.co.uk/uncategorized/cloning-backpack/'>Backpack-inspired organisation tool</a>, Rucksack. At the time, i only just got the basics working, and it was nowhere near &#8220;production ready&#8221;.</p>

<p>Now, it still isn&#8217;t really &#8220;production ready&#8221;, but it has drastically improved these past few months. In August, it started out looking like:</p>
<p style='text-align:left'><a href='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/picture-11.png'><img alt='' class='alignnone size-thumbnail wp-image-276' height='138' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/picture-11-300x132.png' title='rck_overview' width='300' /></a></p>
<p>And now it looks like this: <p style='text-align:left'><a href='http://www.cuppadev.co.uk/wp-content/uploads/2008/10/rck-new.png'><img alt='' class='alignnone size-thumbnail wp-image-316' height='156' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/10/rck-new-300x156.png' title='rck-new' width='300' /></a></p></p>

<p>Which to say the least, is a big improvement.</p>

<p>But &#8221;<em>What's new?</em>&#8221;, you may ask. Well apart from the new grey spaced out look&#8230;</p>
<ul>
	<li>You can now see a general overview of recent activity</li>
	<li>You can now <strong>upload files</strong></li>
	<li>You can <strong>send emails to to pages</strong></li>
	<li>Basic <strong>reminders</strong> have been implemented with email functionality</li>
	<li><strong>Journals and Status</strong> (think Twitter) have been implemented</li>
	<li>Fed-up of the default page width? You can now <strong>resize Pages</strong>!</li>
	<li>Pages can now be <strong>shared to the public</strong></li>
	<li>Client-side interface re-written in <strong>jQuery</strong></li>
	<li><strong>Bug fixes</strong> and <strong>stability improvements</strong></li>
</ul>
<p>So safe to say, a lot of improvements. But still, a long way to go before it is truly useful for every day organisation.</p>

<p>As always, Rucksack is open source and can be <a href='http://github.com/jamesu/rucksack/tree/master'>checked out on github</a>.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>iPhone Developer NDA Lifted. </title>

		<link>http://www.cuppadev.co.uk/iphone-developer-nda-lifted/</link>
		<comments>http://www.cuppadev.co.uk/iphone-developer-nda-lifted/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=294</guid>
		<description><![CDATA[<p>After trawling the interwebs today, i came across this little gem on the Apple web site:</p>
<a href='http://www.cuppadev.co.uk/wp-content/uploads/2008/10/picture-1.png'><img alt='' class='alignnone size-thumbnail wp-image-295' height='139' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/10/picture-1-300x139.png' title='picture-1' width='300' /></a>
<p>( <a href='http://developer.apple.com/iphone/program/?nda'>http://developer.apple.com/iphone/program/?nda</a> )</p>

<p>Well, it&#8217;s about time.</p>

<p>Being very interested in iPhone development myself, i naturally have posted quite a bit about the iPhone on this blog. However, due to the NDA i couldn&#8217;t really post a lot - the &#8221;<a href='http://www.cuppadev.co.uk/platforms/running-your-own-iphone-applications-without-paying-the-developer-fee/'>Running your own iPhone applications without paying the developer fee</a>&#8221; was pushing it.</p>

<p>In any case, look forward to more iPhone-related development posts.</p>]]></description>
		<content:encoded><![CDATA[<p>After trawling the interwebs today, i came across this little gem on the Apple web site:</p>
<a href='http://www.cuppadev.co.uk/wp-content/uploads/2008/10/picture-1.png'><img alt='' class='alignnone size-thumbnail wp-image-295' height='139' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/10/picture-1-300x139.png' title='picture-1' width='300' /></a>
<p>( <a href='http://developer.apple.com/iphone/program/?nda'>http://developer.apple.com/iphone/program/?nda</a> )</p>

<p>Well, it&#8217;s about time.</p>

<p>Being very interested in iPhone development myself, i naturally have posted quite a bit about the iPhone on this blog. However, due to the NDA i couldn&#8217;t really post a lot - the &#8221;<a href='http://www.cuppadev.co.uk/platforms/running-your-own-iphone-applications-without-paying-the-developer-fee/'>Running your own iPhone applications without paying the developer fee</a>&#8221; was pushing it.</p>

<p>In any case, look forward to more iPhone-related development posts.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Disqus</title>

		<link>http://www.cuppadev.co.uk/disqus/</link>
		<comments>http://www.cuppadev.co.uk/disqus/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=292</guid>
		<description><![CDATA[<p>As a little experiment, i decided to move this blog&#8217;s comments to <a href='http://disqus.com/'>Disqus</a>, a third party service which well&#8230; hosts comments.</p> <p>Setup was extremely simple. It went something like this:</p> <ul> <li>Make a disqus account</li> <li>Add cuppadev.co.uk as a site</li> <li>Download wordpress plugin</li> <li>Install wordpress plugin on server</li> <li>Click "Import" button</li> <li>Comments now go through disqus</li> </ul> <p>Wow&#8230; that was quite simple. And i like simple.</p> <p>Hopefully this will help weed out the tons of spam i have been getting recently. I think also that it&#8217;s simpler to use, so who knows, i might get more comments.</p> <p>Now, where...]]></description>
		<content:encoded><![CDATA[<p>As a little experiment, i decided to move this blog&#8217;s comments to <a href='http://disqus.com/'>Disqus</a>, a third party service which well&#8230; hosts comments.</p>

<p>Setup was extremely simple. It went something like this:</p>
<ul>
	<li>Make a disqus account</li>
	<li>Add cuppadev.co.uk as a site</li>
	<li>Download wordpress plugin</li>
	<li>Install wordpress plugin on server</li>
	<li>Click "Import" button</li>
	<li>Comments now go through disqus</li>
</ul>
<p>Wow&#8230; that was quite simple. And i like simple.</p>

<p>Hopefully this will help weed out the tons of spam i have been getting recently. I think also that it&#8217;s simpler to use, so who knows, i might get more comments.</p>

<p>Now, where did i leave those blog posts?</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Software Development Meme</title>

		<link>http://www.cuppadev.co.uk/software-development-meme/</link>
		<comments>http://www.cuppadev.co.uk/software-development-meme/#comments</comments>
		<pubDate>Wed, 17 Sep 2008 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=286</guid>
		<description><![CDATA[<p>Looks like i&#8217;ve been tagged with a meme. This time, it&#8217;s about Software Development, courtesy of <a href='http://blog.azazil.net'>Gary Vaughan</a>. Since that&#8217;s my field, i thought i might as well respond to it.</p> <h3>How old were you when you first started programming?</h3> <p>About 10.</p> <h3>How did you get started in programming?</h3> <p>I picked up a copy of <a href='http://en.wikipedia.org/wiki/Borland_Delphi'>Borland Delphi</a> from <a href='http://www.pcplus.co.uk/'>PC Plus</a> (a home computing magazine here in the UK). Ran my first program, and thought it was kind-of cool. Little did i know what i would be getting myself into.</p> <h3>What was your first language?</h3> <p>Programming language? Delphi,...]]></description>
		<content:encoded><![CDATA[<p>Looks like i&#8217;ve been tagged with a meme. This time, it&#8217;s about Software Development, courtesy of <a href='http://blog.azazil.net'>Gary Vaughan</a>. Since that&#8217;s my field, i thought i might as well respond to it.</p>
<h3>How old were you when you first started programming?</h3>
<p>About 10.</p>
<h3>How did you get started in programming?</h3>
<p>I picked up a copy of <a href='http://en.wikipedia.org/wiki/Borland_Delphi'>Borland Delphi</a> from <a href='http://www.pcplus.co.uk/'>PC Plus</a> (a home computing magazine here in the UK). Ran my first program, and thought it was kind-of cool. Little did i know what i would be getting myself into.</p>
<h3>What was your first language?</h3>
<p>Programming language? Delphi, otherwise known as Object Pascal. Language? English.</p>
<h3>What was the first real program you wrote?</h3>
<p>The first ever would of course be a &#8220;Hello World&#8221;. The first one which i would consider &#8220;real&#8221; would be a neat web-based file storage app, which i didn&#8217;t make until many months later.</p>
<h3>What languages have you used since you started programming?</h3>
<p>C, C++, C#, Pascal, Java, Python, Ruby, JavaScript, SQL, Visual Basic. 6502 assembly.</p>
<h3>What was your first professional programming gig?</h3>
<p>The first professional programming gig would be freelancing for <a href='http://www.mode7games.com/'>Mode7 Games</a>.</p>
<h3>If you knew then what you know now, would you have started programming?</h3>
<p>No. Instead, i would have jumped on the <a href='http://en.wikipedia.org/wiki/Dot-com_bubble'>dot com boom</a> by hiring a set of competent programmers and making some really cool website with substance, pulling in crazed investors by the hordes.</p>

<p>Maybe after the bubble burst i would think about starting programming.</p>
<h3>If there is one thing you learned along the way that you would tell new developers, what would it be?</h3>
<p>Problem solving is the most crucial aspect of programming. Make sure you learn how to do it.</p>
<h3>What's the most fun you've ever hadÖ programming?</h3>
<p>After &#8220;Hello World&#8221; ran&#8230; it all went downhill from there. :)</p>
<h3>Who's next?</h3><a href='http://blog.nihilogic.dk/'>Nihilogic</a>]]></content:encoded>
	</item>
	
	<item>
		<title>Google Chrome</title>

		<link>http://www.cuppadev.co.uk/google-chrome/</link>
		<comments>http://www.cuppadev.co.uk/google-chrome/#comments</comments>
		<pubDate>Tue, 02 Sep 2008 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=280</guid>
		<description><![CDATA[<p>Well it looks like <a href='http://www.google.com'>Google</a> have finally jumped on the Web Browser bandwagon. <a href='http://www.google.com/chrome'>Google Chrome</a> was released today, which looks like a very interesting browser indeed.</p> <p style='text-align:center'><a href='http://www.cuppadev.co.uk/wp-content/uploads/2008/09/picture-2.png'><img alt='' class='alignnone size-thumbnail wp-image-281' height='195' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/09/picture-2-300x195.png' style='border:none' title='picture-2' width='300' /></a></p> <p>Trying it out myself, i couldn&#8217;t figure what the fuss was about until i read the <a href='http://www.google.com/googlebooks/chrome/index.html'>associated comic</a>, which goes into details about the JavaScript engine, tabs in separate processes for security, and of course <a href='http://gears.google.com/'>Gears</a> integration.</p> <p>So all in all, i think it is a nice and refreshing take on the web browser. For far too...]]></description>
		<content:encoded><![CDATA[<p>Well it looks like <a href='http://www.google.com'>Google</a> have finally jumped on the Web Browser bandwagon. <a href='http://www.google.com/chrome'>Google Chrome</a> was released today, which looks like a very interesting browser indeed.</p>
<p style='text-align:center'><a href='http://www.cuppadev.co.uk/wp-content/uploads/2008/09/picture-2.png'><img alt='' class='alignnone size-thumbnail wp-image-281' height='195' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/09/picture-2-300x195.png' style='border:none' title='picture-2' width='300' /></a></p>
<p>Trying it out myself, i couldn&#8217;t figure what the fuss was about until i read the <a href='http://www.google.com/googlebooks/chrome/index.html'>associated comic</a>, which goes into details about the JavaScript engine, tabs in separate processes for security, and of course <a href='http://gears.google.com/'>Gears</a> integration.</p>

<p>So all in all, i think it is a nice and refreshing take on the web browser. For far too long i have had to put up with Firefox the memory hog being slow and chuggy, Safari randomly crashing, Opera not being good enough, and Internet Explorer which is like driving a stake through my ears. Google Chrome on the other hand&#8230; not bad.</p>

<p>Still, it does have a few problems. Rather than moan about them though, i&#8217;ll just be concise and list them all:</p>
<ul>
<li>No <strong>getImageData</strong> support in the Canvas</li>
<li>Runs on Windows only (for now)</li>
<li>Scrolling seems chunky</li>
<li>The Flash plugin slows everything down just as usual</li>
</ul>
<p>Apart from that, great. Will be interesting to see how Google Chrome advances in the future.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>A good use for &quot;:group&quot; in Rails</title>

		<link>http://www.cuppadev.co.uk/a-good-use-for-group-in-rails/</link>
		<comments>http://www.cuppadev.co.uk/a-good-use-for-group-in-rails/#comments</comments>
		<pubDate>Sun, 24 Aug 2008 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=260</guid>
		<description><![CDATA[<p>Recently i needed to make a custom view for activity logs in my <a href='http://www.rubyonrails.org'>Ruby on Rails</a> app. I wanted to create a summary of the activity <strong>grouped by the day</strong>, <strong>without any duplicates</strong>. e.g. if i performed an action an object twice, i didn&#8217;t want it to be listed twice.</p> <p>So how does one do this in Rails? Simple - use the &#8221;<strong>:group</strong>&#8221; (i.e. GROUP BY) parameter when doing a <strong>find()</strong> to combine results into single results.</p> <h3>The nitty gritty</h3> <p>For reference i used the following schema on my logs:</p> <pre><code> create_table "application_logs" do |t| t.integer "rel_object_id" t.text "object_name"...]]></description>
		<content:encoded><![CDATA[<p>Recently i needed to make a custom view for activity logs in my <a href='http://www.rubyonrails.org'>Ruby on Rails</a> app. I wanted to create a summary of the activity <strong>grouped by the day</strong>, <strong>without any duplicates</strong>. e.g. if i performed an action an object twice, i didn&#8217;t want it to be listed twice.</p>

<p>So how does one do this in Rails? Simple - use the &#8221;<strong>:group</strong>&#8221; (i.e. GROUP BY) parameter when doing a <strong>find()</strong> to combine results into single results.</p>
<h3>The nitty gritty</h3>
<p>For reference i used the following schema on my logs:</p>
<pre><code>
  create_table "application_logs" do |t|
    t.integer  "rel_object_id"
    t.text     "object_name"
    t.string   "rel_object_type"
    t.datetime "created_on",
    t.integer  "created_by_id",
    t.boolean  "is_private",
    t.boolean  "is_silent",
    t.integer  "action_id",
    t.integer  "page_id",
  end
</code></pre>
<p>In my case, most of my objects were linked to pages. And for those, i only wanted page activity to be listed once. e.g. &#8220;Modified page X&#8221; instead of &#8220;Modified object 1 on page X&#8221;, &#8220;Modified object 2 on page X&#8221;.</p>

<p>So i needed to group by <strong>page_id</strong>, <strong>created_by_id</strong>, <strong>created_on</strong> (as a date), and both <strong>rel_object_id and rel_object_id</strong>.</p>

<p>First i came up with the following <strong>:group</strong> :</p>
<pre><code>
"created_by_id, 
 date(created_on), 
 page_id, 
 rel_object_type || rel_object_id"
</code></pre><em>Note: the "||" operator in SQLite and PostgreSQL concatenates strings.</em>
<p>Unfortunately that doesn&#8217;t work properly since i have other objects which aren&#8217;t linked to a page, and they would only get listed once (since for all of them <strong>page_id</strong> would be NULL). So i needed to use the &#8220;CASE&#8221; statement to differentiate between the two:</p>
<pre><code>
"created_by_id, 
 date(created_on), 
 CASE page_id ISNULL 
   WHEN 1 THEN rel_object_type || rel_object_id 
   ELSE page_id 
 END"
</code></pre>
<p>So now both the page objects and the regular objects were listed once per day. But there was another problem.</p>

<p>After the query i used the <strong>group_by</strong> method to group everything into blocks based on the date. But i also use the <a href='http://mad.ly/2008/04/09/rails-21-time-zone-support-an-overview/'>time zone support</a> in Rails 2.1, and since the database stores its dates in UTC, i got this rather odd issue where in certain circumstances objects were listed twice.</p>

<p>In reality they were the same date, in <strong>UTC</strong>. But not in the <strong>current timezone</strong> i was using. So after a bit of investigation i came up with a solution. I needed to offset the date in the query by the UTC offset for the current timezone.</p>

<p>It turns out that there are a ton of different ways to do it, depending on which database you are using. In my case i was testing with <a href='http://www.sqlite.org/'>SQLite</a>, so the following sufficed:</p>
<pre><code>
date(created_on, '+#{Time.zone.utc_offset} seconds')
</code></pre>
<p>And for <a href='http://mysql.org'>MYSQL</a> (and perhaps others), using INTERVAL works:</p>
<pre><code>
date(created_on + INTERVAL #{Time.zone.utc_offset} SECOND)
</code></pre>
<p>Of course, this still has its problems. Like what about daylight savings time?</p>

<p>Unfortunately, since there doesn&#8217;t seem to be any set standard for specifying what timezone to evaluate times in, you are either going to have to write a specific case for it, or just put up with the dates potentially being off for an hour or two.</p>
<h3>The end result</h3>
<p>Well, it looks something like this:</p>
<p style='text-align:center'><a href='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/rck_overview.png'><img alt='' class='alignnone size-thumbnail wp-image-276' height='138' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/rck_overview-300x138.png' title='rck_overview' width='300' /></a></p>]]></content:encoded>
	</item>
	
	<item>
		<title>Cloning Backpack</title>

		<link>http://www.cuppadev.co.uk/cloning-backpack/</link>
		<comments>http://www.cuppadev.co.uk/cloning-backpack/#comments</comments>
		<pubDate>Sun, 17 Aug 2008 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=242</guid>
		<description><![CDATA[<p>Just over a month ago now, i got sick of my chief open source project, <a href='http://github.com/jamesu/railscollab/tree/master'>RailsCollab</a>. Nobody seemed interested in it, and the code was growing tired and deprecated. So i decided to try making another open <a href='http://www.rubyonrails.org'>Ruby on Rails</a> project.</p> <p>Like my previous chief open source project, i decided my new one was also going to be a clone. Mainly because i couldn&#8217;t really come up with anything else more interesting, bu i also wanted to see what it would be like cloning something from scratch.</p> <p>After much deliberation, i decided the focus of my attention would...]]></description>
		<content:encoded><![CDATA[<p>Just over a month ago now, i got sick of my chief open source project, <a href='http://github.com/jamesu/railscollab/tree/master'>RailsCollab</a>. Nobody seemed interested in it, and the code was growing tired and deprecated. So i decided to try making another open <a href='http://www.rubyonrails.org'>Ruby on Rails</a> project.</p>

<p>Like my previous chief open source project, i decided my new one was also going to be a clone. Mainly because i couldn&#8217;t really come up with anything else more interesting, bu i also wanted to see what it would be like cloning something from scratch.</p>

<p>After much deliberation, i decided the focus of my attention would be to clone another of 37Signals&#8217; products. Not <a href='http://basecamphq.com/'>Basecamp</a> this time - that has already been done to death. Instead, i decided to try and clone&#8230; <a href='http://www.backpackit.com/'><strong>Backpack</strong></a>!</p>
<a href='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/picture-2.png'><img alt='' class='alignnone size-thumbnail wp-image-247' height='151' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/picture-2-300x151.png' title='backpack' width='300' /></a>
<p>Interestingly while i looked far and wide for a comparable product, i couldn&#8217;t seem to find anything. The only one that came remotely close was <a href='http://tiddlywiki.org/'>TiddlyWiki</a>. But while that was free and open, i felt it completely missed the niche that Backpack filled. Collaboratively edited pages, which are actually easy to edit.</p>
<h3>The nitty gritty</h3>
<p>First of all - before i even writ one line of code - i decided to check out Backpack&#8217;s underlying data models. They told me a lot about how Backpack worked, and of course they gave me a few hints about what data i should store.</p>

<pre><code>Backpack

Models

(generally created and modified dates exist for all of these) 

Pages
    - scope
    - title
    - email_address

    Belongings (basically reference from page -&amp;gt; list item + position.
                     referred to by id)
    Lists
        - name
        List Items
            - completed
            - content
            - order
    Notes
        - title
        - content
    Seperators
        - name
        - page id
    Tags
        - name
    WriteboardLink
Writeboard
    - title

    WriteboardPages
        - content
Reminders
    - at time
    - content
    - creator
    - remindees [Users]
Emails
    - title
    - content
Statuses (one per user)
    - message (text)
    - last update
    - owner
Journals
    - body (length=255)
    - owner
    - last update
Users
    - name
Calendar
    - color
    - subscription url (pulling from other calendar?)
    - name
    - token (used in url for sharing)

    Events
        - title
        - occurs_at
        - occurs_until
        - reminded_at
        - remind (bool, note fixed time before)
        - all day (bool)</code></pre>

<p>Next i decided to sketch out some of the models. <strong>has_many</strong>, <strong>belongs_to</strong>, etc. I also decided to give some models such as the &#8220;Belongings&#8221; different names, as i thought the originals sucked.</p>

<p>(Note that by this time i decided to concentrate my efforts on making a <strong>Page editor</strong>, as i felt that was the key defining feature)</p>

<p>After i got that out the way, i built a simple page <a href='http://en.wikipedia.org/wiki/Representational_State_Transfer'>RESTful</a> scaffold for editing pages. All it did was render page slots and the widgets contained therein. What it lacked was the rather crucial <a href='http://en.wikipedia.org/wiki/AJAX'>AJAX</a> editing that was prevalent in Backpack.</p>

<p>So then i decided to take a closer look at how Backpack&#8217;s AJAX page editing worked. It turned out that there were a few crucial components:</p>

<ul>
<li><strong>The widgets</strong> - the real content of the page. e.g. Notes, Lists, Dividers</li>

<li><strong>The insertion bar</strong> - this pops up when you hover your mouse over the top or bottom of the widgets.</li>

<li><strong>The action bar</strong> - this pops up when you click &#8220;Insert Here&#8221; on the insertion bar, and is inserted between the relevant widgets.</li>

<li><strong>The actions on the action bar</strong> - when you click on them, either a widget is inserted (e.g. list) or a form is shown in the slate.</li>

<li><strong>The slate</strong> - this either exists in a container before the widgets, or in the action bar. It contains most of the forms.</li>
</ul>

<p>These components are almost exclusively powered by client-side Javascript. Only when you get to the parts where content is added, edited, or removed from a page do you get an AJAX request sent to the server. e.g. Inserting edit forms, adding widgets and belongings, etc.</p>

<p>What you get back from the server is usually Javascript code which alters the content in the page according to the request.</p>

<p>So once i figured all that out, i eventually managed to implement a rather nifty AJAX-powered page editor which somewhat resembled Backpack&#8217;s. Mission accomplished!</p>
<h3>The result</h3><a href='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/picture-11.png'><img alt='' class='alignnone size-thumbnail wp-image-246' height='132' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/picture-11-300x132.png' title='rucksack' width='300' /></a>
<p>Well, here it is. It&#8217;s called Rucksack, and it acts similarly to Backpack. You can make pages, and share them with others to edit collaboratively. Strange but true.</p>

<p>&#8221;<em>Now wait a minute!</em>&#8221; you might be thinking, &#8221;<em>it looks like crap, and it doesn't implement everything</em>&#8221;. True, but remember that i was only interested in implementing a <strong>proof-of-concept</strong> page editor. I wasn&#8217;t planning on implementing everything and making it look nice. That is for later.</p>

<p>Now while i did start off thinking of Rucksack as a Backpack clone, i don&#8217;t think it is the best frame of mind to be in. So for future development, i will be concentrating less on copying backpack, and more on tailoring it to what i think will be useful in organising.</p>

<p>Meanwhile, i have put the code up on <a href='https://github.com/jamesu/rucksack/tree'>github for anyone to check out</a>.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>JavaScript 2 dead? Have no fear, haXe is here!</title>

		<link>http://www.cuppadev.co.uk/javascript-2-dead-have-no-fear-haxe-is-here/</link>
		<comments>http://www.cuppadev.co.uk/javascript-2-dead-have-no-fear-haxe-is-here/#comments</comments>
		<pubDate>Wed, 13 Aug 2008 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=234</guid>
		<description><![CDATA[<p>Earlier on, i noticed this little gem on reddit:</p> <p style='text-align:left'><img alt='' class='alignnone size-full wp-image-235' height='58' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/picture-1.png' title='picture-1' width='428' /></p> <p>Which led me to this rather interesting mailing list post by Douglas Crockford:</p> <pre><code> I apologize for my ultrablunt comment. Let me be clear about what I meant. It was decided at the Oslo meeting that the project formerly known as <strong>ES4 is no more</strong>. Instead, there will be a new project, Harmony, which will be the work of a unified working group. We have not yet agreed on a set of goals for Harmony. I recommend that we close...]]></description>
		<content:encoded><![CDATA[<p>Earlier on, i noticed this little gem on reddit:</p>
<p style='text-align:left'><img alt='' class='alignnone size-full wp-image-235' height='58' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/picture-1.png' title='picture-1' width='428' /></p>
<p>Which led me to this rather interesting mailing list post by Douglas Crockford:</p>
<pre><code>
I apologize for my ultrablunt comment. Let me be clear about what I 
meant. It was decided at the Oslo meeting that the project formerly 
known as <strong>ES4 is no more</strong>. Instead, there will be a new project, 
Harmony, which will be the work of a unified working group. We have 
not yet agreed on a set of goals for Harmony.

I recommend that we close the ES4 list and open a harmony list to 
support this new effort.
</code></pre>
<p>Looks like nobody can agree on any set goals for JavaScript 2 (i.e. ES4). Which leads me to think that as with a lot of web standards, JavaScript 2 is just a pipe dream.</p>
<p style='text-align:left'><a href='http://www.haxe.org'><img src='http://cuppadev.co.uk/assets/2007/10/4/haxe_banner.png' style='border:0px;' /></a></p>
<p>Fortunately though, the real world has a solution which already works. Its called <a href='http://www.haxe.org'>haXe</a>, and it implements a lot of what JavaScript 2 <a href='http://blog.haxe.org/entry/25'>should be</a>.</p>

<p>So instead of waiting about for some standards crackpots trying to cobble together a standard, you can write some real code.</p>

<p>Have fun with haXe.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Fuzzy Times</title>

		<link>http://www.cuppadev.co.uk/fuzzy-times/</link>
		<comments>http://www.cuppadev.co.uk/fuzzy-times/#comments</comments>
		<pubDate>Thu, 07 Aug 2008 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=218</guid>
		<description><![CDATA[<p>Recently i have been writing a simple web-based reminder app which requires one to input dates and times. To input the date and time, normally one would add some sort of calendar widget which pops up.</p> <p style='text-align:center'><img alt='' class='alignnone size-thumbnail wp-image-223' height='185' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/calendar-widget.png' title='calendar-widget1' width='138' /></p> <p>But personally i think this tends to be really awkward, especially if you don&#8217;t want to be specific about dates or times. e.g. Speculative Opportunities. It also requires a lot of mouse clicking to find and enter the correct date and time.</p> <p style='text-align:center'><img alt='' class='alignnone size-thumbnail wp-image-220' height='143' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/reminders-parsing.png' title='reminders-parsing' width='275' /></p>...]]></description>
		<content:encoded><![CDATA[<p>Recently i have been writing a simple web-based reminder app which requires one to input dates and times. To input the date and time, normally one would add some sort of calendar widget which pops up.</p>
<p style='text-align:center'><img alt='' class='alignnone size-thumbnail wp-image-223' height='185' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/calendar-widget.png' title='calendar-widget1' width='138' /></p>
<p>But personally i think this tends to be really awkward, especially if you don&#8217;t want to be specific about dates or times. e.g. Speculative Opportunities. It also requires a lot of mouse clicking to find and enter the correct date and time.</p>
<p style='text-align:center'><img alt='' class='alignnone size-thumbnail wp-image-220' height='143' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/reminders-parsing.png' title='reminders-parsing' width='275' /></p>
<p>Fortunately, there are libraries about which aim to solve this issue by allowing you to specify the time in English. Typically they are referred to as &#8220;Natural language&#8221; date/time parsers. In my case, i found one called <a href='http://chronic.rubyforge.org/'>Chronic</a> which is distributed as a gem for Ruby. It has even got a nice <a href='http://www.rubyinside.com/chronic-ruby-date-time-parser-screencast-263.html'>screencast</a>.</p>
<pre><code>sudo gem install chronic</code></pre>
<p>Consisting of only one public function, Chronic is really easy to use:</p>
<pre><code>
require 'chronic'
Chronic.parse("tomorrow at 5")
 #=> Fri Aug 08 17:00:00 +0100 2008
</code></pre>
<p>See? Nice and simple. We can also use the options to help chronic get the right time. e.g. If i really meant to say &#8220;Tomorrow at 5 AM&#8221;, i could fix it like this:</p>
<pre><code>
require 'chronic'
Chronic.parse("tomorrow at 5", :ambiguous_time_range => :none)
 #=> Fri Aug 08 5:00:00 +0100 2008
</code></pre>
<p>The options you can choose from are as follows:</p>
<ul>
<li><strong>:context</strong> - the context in which the time is assessed (<strong>:past</strong> or <strong>:future</strong>).</li>
<li><strong>:now</strong> - current time.</li>
<li><strong>:guess</strong> - if false, this returns a time range instead of guessing at a specific time.</li>
<li><strong>:ambiguous_time_range</strong> - range in hours in which an ambiguous time will be resolved. Best to think of it as hours to skip in the day when picking a time. e.g. setting this to 18 and inputting 5 will result in 5am the next day being chosen.</li>
</ul>
<p>Sadly i couldn&#8217;t seem to find any way of setting which time zone to evaluate the time in. This would have been useful when working with <a href='http://mad.ly/2008/04/09/rails-21-time-zone-support-an-overview/'>Ruby on Rails 2.1's new TimeZone support</a>. Fortunately though, i figured out a workaround which is as follows:</p>
<pre><code>
# grab time using current time zone as reference
ctime = Chronic.parse(value, :now => Time.zone.now)
# re-interpret time in current timezone
ctime = Time.zone.local(ctime.year, ctime.mon, ctime.day, ctime.hour, ctime.min, ctime.sec)
</code></pre>
<p>Basically this gives Chronic the time in the current time zone, which deals with relative times (e.g. &#8220;tomorrow&#8221;). It also re-interprets the calculated time in case you are a bit more specific (e.g. &#8220;5AM&#8221;).</p>

<p>For something a bit less hackish, one might want to check out <a href='http://github.com/technoweenie/chronic/tree/master'>technoweenie's fork on github</a>. This appears to allow you to tell Chronic to use a different Time class for calculating times, which should solve the problem.</p>

<p>So to conclude, i think Chronic is a nice and simple solution that works rather nicely for common cases.</p>
<h3>Other libraries</h3>
<p>If you aren&#8217;t using Ruby, have no fear. There are similar &#8220;Natural language&#8221; parsers available for other programming environments which work in a similar fashion to Chronic.</p>
<ul>
<li><a href='http://www.datejs.com/'>Datejs</a> for JavaScript</li>
<li><a href='http://code.google.com/p/parsedatetime/'>parsedatetime</a> for Python</li>
<li><a href='http://search.cpan.org/~schubiger/DateTime-Format-Natural-0.71/lib/DateTime/Format/Natural.pm'>DateTime::Format::Natural</a> for Perl</li>
<li><a href='http://www.codeplex.com/DateTimeEnglishParse'>DateTimeEnglishParser</a> for .net</li>
</ul>]]></content:encoded>
	</item>
	
	<item>
		<title>Brain-Dead Canvas Quirk</title>

		<link>http://www.cuppadev.co.uk/brain-dead-canvas-quirk/</link>
		<comments>http://www.cuppadev.co.uk/brain-dead-canvas-quirk/#comments</comments>
		<pubDate>Sat, 02 Aug 2008 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=165</guid>
		<description><![CDATA[<p>The <a href='http://www.whatwg.org/specs/web-apps/current-work/#the-canvas'>HTML5 Canvas</a>. Great, isn&#8217;t it? You can draw pretty much anything you want in a pre-defined area. In more recent browsers, you can even get &amp; set pixel data too, so you pretty much have full control over how things look.</p> <h3>The problem</h3> <p>Unfortunately, the Canvas suffers from a pretty brain-dead design flaw. That is while you can get and set pixels, you cannot control when the pixel data you grab with <strong>getPixelData()</strong> will be freed from memory. This is exacerbated by the fact that the whole interface runs on top of JavaScript.</p> <p>&#8221;<em>Now wait a minute</em>&#8221;, you...]]></description>
		<content:encoded><![CDATA[<p>The <a href='http://www.whatwg.org/specs/web-apps/current-work/#the-canvas'>HTML5 Canvas</a>. Great, isn&#8217;t it? You can draw pretty much anything you want in a pre-defined area. In more recent browsers, you can even get &amp; set pixel data too, so you pretty much have full control over how things look.</p>
<h3>The problem</h3>
<p>Unfortunately, the Canvas suffers from a pretty brain-dead design flaw. That is while you can get and set pixels, you cannot control when the pixel data you grab with <strong>getPixelData()</strong> will be freed from memory. This is exacerbated by the fact that the whole interface runs on top of JavaScript.</p>

<p>&#8221;<em>Now wait a minute</em>&#8221;, you might think &#8221;<em>doesn't JavaScript have garbage collection for this sort of stuff</em>?&#8221;. Well, yes. The trouble is, JavaScript has <strong>no standardized garbage collection system</strong>, so depending on which browser you happen to be using it&#8217;s pot luck whether or not your pixel data will get freed on time.</p>
<h3>An example</h3>
<p>To start off with, <a href='http://www.cuppadev.co.uk/assets/canvas-quirk.html'>here's a really simple example test case</a>, using &#8221;<strong>putImageData(getImageData())</strong>&#8221;.</p>

<p>Now lets use a real example here. A while back, you might recall i was writing a <a href='http://www.cuppadev.co.uk/oldbrew/scumm-in-javascript/'>SCUMM interpreter</a> in haXe that just so happened to compile to JavaScript as well. For the SCUMM runtime, i am required to display room graphics overlaid with various objects. The graphics are 8bit and use a palette, and that palette can be changed at runtime.</p>
<p style='text-align:center;'><img alt='R - PALETTE - RGB' class='size-full wp-image-174' height='106' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/palette_mapping.png' title='palette_mapping' width='400' /></p>
<p>For performance reasons, i decode the graphics and store them in Canvas elements using only the red channel. In fact, throughout the graphics processing pipeline, the red channel is the only part of the pixel data i use. I also make heavy use of the native blitting functions (e.g. fillRect).</p>

<p>It&#8217;s not until i come to display the graphics that i re-map the pixels from the red channel into the final colours using the current palette. This requires me to <strong>getImageData()</strong> the current pixels in the canvas, iterate through and set the <strong>data[]</strong>, and then <strong>putImageData()</strong> back to the Canvas for the final result.</p>

<p>The trouble is since i am re-mapping the pixels every frame, memory usage on certain browsers (<a href='http://www.opera.com/'>Opera</a>, <a href='http://www.mozilla.com/firefox/'>Firefox</a>) <strong>skyrockets</strong> up to a certain threshold - anything up to 2gb depending on what is happening.</p>
<p style='text-align:center;'><img alt='' class='alignnone size-medium wp-image-178' height='75' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/08/mem_compare_testcase1.png' title='mem_compare_testcase1' width='442' /></p>
<p>For the test case running on <a href='http://www.apple.com/macosx'>OS X</a>, Opera&gt; tops out at ~600mb. <a href='http://www.webkit.org'>Webkit</a> and Firefox both top out at around 1.25gb (honestly though, i just stopped looking as it was getting stupid). It&#8217;s not until i either suspend re-draw and wait several seconds, or simply close the browser window that memory usage returns to normal.</p>

<p>Oddly enough when re-mapping the pixels in my SCUMM interpreter (not in the test case), Webkit&#8217;s memory usage stays constant. This flies in the face of what one would expect to happen based on the test case. As for why, it could be anything. The smaller canvas size, assignment of variables - who knows.</p>
<h3>Workarounds?</h3>
<p>Realistic workarounds include:</p>

<ul>
<li>Perform all graphics operations manually on a single set of pixel data (<strong>too slow!</strong>)</li>

<li>Use <strong>drawImage()</strong> as opposed to <strong>getImageData()</strong> &amp; <strong>putImageData()</strong></li>

<li>Limit the amount of screen updates</li>

<li>When working with palletised image data that needs re-mapping, store it as RGB, and re-calculate it <strong>only</strong> when the palette changes</li>

<li>Don&#8217;t use <strong>getImageData()</strong> at all, especially considering it doesn&#8217;t seem to work in Safari at the moment.</li>
</ul>

<p>Either that, or simply implement everything which needs pixel-level graphics manipulation in <a href='http://www.adobe.com/flash/'>Flash</a> or a <a href='http://java.sun.com/applets/'>Java Applet</a>, foregoing the pure Javascript ethic.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Running your own iPhone applications without paying the developer fee</title>

		<link>http://www.cuppadev.co.uk/running-your-own-iphone-applications-without-paying-the-developer-fee/</link>
		<comments>http://www.cuppadev.co.uk/running-your-own-iphone-applications-without-paying-the-developer-fee/#comments</comments>
		<pubDate>Tue, 22 Jul 2008 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=158</guid>
		<description><![CDATA[<p><strong>Note: these instructions are outdated and should not be taken seriously.</strong></p> <p>For those of you wanting to build off-line, native applications for the <a href='http://apple.com/iphone'>iPhone</a> / <a href='http://www.apple.com/ipodtouch/'>iPod Touch</a> (with the <a href='http://www.apple.com/iphone/softwareupdate/'>2.0 Software Update</a>), you might have been disappointed to hear you need to shelve out $99 yearly for the privilege of being able to run your applications on a real iPhone.</p> <p>Ok, $99 might not be a lot, but one also has to consider when you come to deploy your app for real, it might not pass through the rather stringent screening process to get it to the...]]></description>
		<content:encoded><![CDATA[<p><strong>Note: these instructions are outdated and should not be taken seriously.</strong></p>
<p>For those of you wanting to build off-line, native applications for the <a href='http://apple.com/iphone'>iPhone</a> / <a href='http://www.apple.com/ipodtouch/'>iPod Touch</a> (with the <a href='http://www.apple.com/iphone/softwareupdate/'>2.0 Software Update</a>), you might have been disappointed to hear you need to shelve out $99 yearly for the privilege of being able to run your applications on a real iPhone.</p>

<p>Ok, $99 might not be a lot, but one also has to consider when you come to deploy your app for real, it might not pass through the rather stringent screening process to get it to the masses through the App Store.</p>

<p>Wouldn&#8217;t it be great if you could deploy any application you wanted for <strong>free</strong>?</p>

<p>Well thanks to the recently released pwnage tool, it&#8217;s now possible to run non-Apple-approved applications on your iPhone though &#8220;Jailbreaking&#8221;. I&#8217;ve spent quite a while trying to figure out how to get this working. Here&#8217;s what i have come up with so far.</p>
<h3>First of all...</h3><em>If you are not using a Mac, or you don't have the <a href='http://developer.apple.com/iphone/'>iPhone SDK</a> installed, or alternatively the "open toolkit", then these instructions will be of no use to you.</em>
<p>If you haven&#8217;t done so yet, Jailbreak your iPhone / iPod touch via the &#8220;pwnage tool&#8221;. For reference, this is what i did:</p>
<ol>
<li><a href='http://blog.iphone-dev.org/post/42931306/pwnagetool-2-0-1'>Download the pwnage tool</a></li>
<li><a href='http://news.metaparadigma.de/?p=347'>Create and transfer Jailbroken firmware using the pwnage tool</a></li>
</ol>
<p>After you&#8217;ve done all that, you&#8217;ll probably notice a new application called &#8220;Cydia&#8221; appears on your iPhone screen. This is basically the way end-users can access a wide range of free &#8220;homebrew&#8221; applications on their Jailbroken iPhone&#8217;s. If you want to deploy your application to end-users, you&#8217;ll have to get it into Cydia.</p>

<p>But enough about Cydia for now&#8230;</p>
<h3>I've built applications, how on earth do i get them over to my iPhone?</h3>
<p>If you are using XCode, make sure you set the SDK of your application to &#8220;Device - iPhone OS 2.0&#8221; (or the equivalent if it exists). Then all you need to do is click &#8220;Build and go&#8221;, and your application should appear on your iPhone.</p>

<p>Now you&#8217;ll probably get this rather &#8220;Unexpected error&#8221; popping up if you try and run your application with XCode.</p>

<p>Unfortunately while the pwnage tool allows you to run any application, that application still needs to be signed. So how do you sign it? Well, the best tutorial for that i have found is the &#8221;<a href='http://developer.apple.com/documentation/Security/Conceptual/CodeSigningGuide/Procedures/chapter_3_section_2.html'>Code Signing Guide</a>&#8221; on Apple&#8217;s website.</p>

<p>You&#8217;ll need to make a self-signed certificate using the Keychain Access utility. <del datetime='2008-07-29T13:51:25+00:00'>Then you should run the following commands in a terminal on your built application:</del></p>
<del datetime='2008-07-29T13:51:25+00:00'><pre>
<code>
export CODESIGN_ALLOCATE=/Developer/Platforms/iPhoneOS.platform//Developer/usr/bin/codesign_allocate
codesign -fs "Name of your certificate here" /Path/to/your/built/application.app
</code>
</pre></del><del datetime='2008-07-29T13:51:25+00:00'>Unfortunately even when you do this, you still cannot run your app using XCode, so you can't use any of those fancy debug tools with it. </del><del datetime='2008-07-29T13:51:25+00:00'>In order to run your application, you'll have to copy it over yourself. You can either use OpenSSH (installed through Cydia), or <a href='http://code.google.com/p/iphonedisk/'>iphonedisk</a>. I used OpenSSH, as i had problems with the permissions not being preserved with iphonedisk:
</del><pre>
<code>
<del datetime='2008-07-29T13:51:25+00:00'>scp -r /Path/to/your/built/application.app root@address_of_your_iphone_or_ipod:/Applications/</del>
</code>
</pre><del datetime='2008-07-29T13:51:25+00:00'>Re-load the springboard either by installing something with Cydia, or restarting your iPhone. And hey presto, your app appears!</del>
<p><em>Update:</em> There is now a way to get your apps working directly from XCode. Simply follow the <a href='http://www.246tnt.com/iPhone/#xcode'>instructions here</a>, and you should be able to debug your application straight from XCode. Neat!</p>
<em>Note: there are of course other ways to get your app working, but personally i found signing it to be the most obvious.</em><h3>Right, now my application is ready for public consumption</h3>
<p>Great! So how do we get it into Cydia? Well there are two options:</p>
<ol>
<li>Get the Cydia guy's to host it in their repository</li>
<li><a href='http://www.saurik.com/id/7'>Make your own repository</a></li>
</ol>
<p>Well i couldn&#8217;t figure out how you are meant to contact the Cydia guy&#8217;s to get your application in their repository. Realistically speaking, this is the only way people are going to find your application, considering there is currently no user friendly way to add new repositories to Cydia.</p>

<p>After all, would you really want to type all of this into the terminal to add a single repository?</p>
<pre>
<code>
ssh root@address_of_your_iphone_or_ipod
echo "deb http://location.of/apt_repository/ ./" > /etc/apt/sources.list.d/apt_repository.list
</code>
</pre><h3>To conclude</h3>
<p>If you are really serious about making money off developing iPhone apps, then i&#8217;d cough up and pay the $99 developer fee. That way you&#8217;ll be able to target <strong>every</strong> iPhone / iPod Touch user, while being able to charge a fee for downloading.</p>

<p>If however you have an application Apple are never going to distribute (e.g. emulators), or you are just playing about and don&#8217;t mind the lack of XCode integration for on-device debugging, then developing for Jailbroken devices is for you. Personally though i&#8217;d recommend you compile your own &#8220;open toolkit&#8221;, as developing your own unofficial apps using the official SDK is legally questionable.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>RailsCollab Alpha 3</title>

		<link>http://www.cuppadev.co.uk/railscollab-alpha-3/</link>
		<comments>http://www.cuppadev.co.uk/railscollab-alpha-3/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=150</guid>
		<description><![CDATA[<p>Hot off the presses, i&#8217;ve just pushed alpha 3 of RailsCollab to both <a href='http://rubyforge.org/projects/railscollab/'>Rubyforge</a> and <a href='http://github.com/jamesu/railscollab/commits/release-alpha3'>Github</a>. <h3>Railscollab? What's that?</h3> Railscollab is a re-write of the Project Management solution <a href='http://www.activecollab.com'>ActiveCollab</a> (otherwise known as <a href='http://www.projectpier.org'>ProjectPier</a>), which instead is written in <a href='http://www.ruby-lang.org'>Ruby</a> and runs on the <a href='http://www.rubyonrails.org/'>Ruby on Rails</a> web development framework. <h3>Why on earth would you want to do that?</h3> Good question. Well, it all started when the developer of ActiveCollab announced they were ditching the open source version and going commercial and closed source. Of course, there were people like me that didn&#8217;t like that.</p>...]]></description>
		<content:encoded><![CDATA[<p>Hot off the presses, i&#8217;ve just pushed alpha 3 of RailsCollab to both <a href='http://rubyforge.org/projects/railscollab/'>Rubyforge</a> and <a href='http://github.com/jamesu/railscollab/commits/release-alpha3'>Github</a>. <h3>Railscollab? What's that?</h3> Railscollab is a re-write of the Project Management solution <a href='http://www.activecollab.com'>ActiveCollab</a> (otherwise known as <a href='http://www.projectpier.org'>ProjectPier</a>), which instead is written in <a href='http://www.ruby-lang.org'>Ruby</a> and runs on the <a href='http://www.rubyonrails.org/'>Ruby on Rails</a> web development framework. <h3>Why on earth would you want to do that?</h3> Good question. Well, it all started when the developer of ActiveCollab announced they were ditching the open source version and going commercial and closed source. Of course, there were people like me that didn&#8217;t like that.</p>

<p>So i decided to make my own fork - however i added a twist. I decided to re-write it using Ruby on Rails, since the original <a href='http://www.php.net'>PHP</a> code was giving me a headache. Plus it seemed like a great way to get to know the Ruby on Rails framework.</p>
<em>Note that around the same time, another fork called ProjectPier arose, which opted to develop from the original PHP code.</em><h3>So what's new?</h3>
<p>Quite a lot, actually. Pretty much everything that was present in ActiveCollab 0.7.x is now implemented, sans the the fancy web-based installer. I&#8217;ve also focussed a lot on fixing bugs and improving stability, as well as enhancing the time tracking components. <p style='text-align:left;'><a href='http://www.cuppadev.co.uk/wp-content/uploads/2008/07/time-tracking-csv1.png'><img alt='Time tracking with CSV export' class='size-thumbnail wp-image-152' height='115' src='http://www.cuppadev.co.uk/wp-content/uploads/2008/07/time-tracking-csv1-300x115.png' title='time-tracking-csv1' width='300' /></a></p> &#8230; and of course there is the configuration editor which takes advantage of Phusion Passenger. <p style='text-align:left;'><a href='http://www.cuppadev.co.uk/assets/rc_cnf.jpg'><img alt='Configuration Editor' src='http://www.cuppadev.co.uk/assets/rc_cnf_th.jpg' title='Configuration Editor' /></a></p> In addition, i have updated the RailsCollab demo, so if you don&#8217;t have the time to set everything up, you can still try out Alpha 3.</p>

<p>I&#8217;d also like to thank <strong>everyone</strong> (you know who you are) who has reported issues with RailsCollab over the past few months. Without your help, i doubt i would have had the willpower to make another release.</p>

<p>So what are you waiting for, <a href='http://freshbrew.cuppadev.co.uk'>try it out already</a>. :)</p>
<strong>Edit:</strong><p style='text-align:left;'><img alt='OpenID Logo' src='http://www.cuppadev.co.uk/assets/2007/8/11/openid.png' title='OpenID Logo' /></p>
<p>Simply select the &#8220;Use OpenID&#8221; checkbox and type in your OpenID to login. An account should automatically be created for you if one does not already exist, provided that your OpenID provider provides a username, email, and name.</p>

<p>You can get an OpenID from many places - one of my favourites being <a href='https://www.myopenid.com/'>myOpenID</a>.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>SCUMM in JavaScript</title>

		<link>http://www.cuppadev.co.uk/scumm-in-javascript/</link>
		<comments>http://www.cuppadev.co.uk/scumm-in-javascript/#comments</comments>
		<pubDate>Wed, 28 May 2008 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=145</guid>
		<description><![CDATA[<p>Soon after bumping into <a href='http://www.haxe.org'>haXe</a> and <a href='http://code.google.com/p/doomedonline/'>Doomed Online</a>, they got me thinking. &#8220;Would it be possible to run <span class='caps'>SCUMM</span> games in flash?&#8221;. The answer to that of course is yes, as was demonstrated by my <a href='http://www.cuppadev.co.uk/2007/11/22/flash-plays-scumm-take-two/'><span class='caps'>SCUMM</span> Interpreter written in haXe</a>. Though as with anything, you really need to spend the <strong>time</strong> to implement everything, and justify it somewhat.</p><p>(Not to mention that Flash 10 is supposedly going to be able to compile C code, thus making my complete port more or less redundant)</p><p>Now i would have stopped there, if i hadn&#8217;t noticed that haXe targets multiple...]]></description>
		<content:encoded><![CDATA[<p>Soon after bumping into <a href='http://www.haxe.org'>haXe</a> and <a href='http://code.google.com/p/doomedonline/'>Doomed Online</a>, they got me thinking. &#8220;Would it be possible to run <span class='caps'>SCUMM</span> games in flash?&#8221;. The answer to that of course is yes, as was demonstrated by my <a href='http://www.cuppadev.co.uk/2007/11/22/flash-plays-scumm-take-two/'><span class='caps'>SCUMM</span> Interpreter written in haXe</a>. Though as with anything, you really need to spend the <strong>time</strong> to implement everything, and justify it somewhat.</p><p>(Not to mention that Flash 10 is supposedly going to be able to compile C code, thus making my complete port more or less redundant)</p><p>Now i would have stopped there, if i hadn&#8217;t noticed that haXe targets multiple platforms, including every web developer&#8217;s best friend, JavaScript. Thus i thought, &#8220;<strong>Would it be possible to run <span class='caps'>SCUMM</span> games in Javascript?</strong>&#8221;. For the answer&#8230; well, take a look!</p><p style='text-align:left;'><a href='http://www.cuppadev.co.uk/assets/hiscumm_js.png'><img alt='OpenQuest in a browser' src='http://www.cuppadev.co.uk/assets/hiscumm_js_th.png' title='OpenQuest in a browser' /></a></p><p>Yes, that is an image of <a href='http://alban.dotsec.net/13.html'>OpenQuest</a> running in a web browser, specifically Firefox. It can run in other browsers too, though to date i have only tested Firefox and Safari, the latter of which mysteriously crashes.</p><p>And if you want, you can <a href='http://stuff.cuppadev.co.uk/hiscumm/js_test.html'>try it yourself by clicking here</a>. A <strong>word of warning though</strong>, it is highly recommended that you use <a href='http://www.mozilla.com/firefox/'>Firefox</a> to run it. Otherwise you might get a nasty crash, or a big disappointment.</p><p>As previously, just about enough is implemented to get the first room of OpenQuest loaded. Actors, verbs, objects, and sounds are not implemented, though it would certainly be possible. However the engine runs <strong>much slower than in Flash</strong>, so i doubt anything that could be considered to be &#8220;playable&#8221; could be implemented with it.</p><p>Still, i feel I&#8217;ve now accomplished what i set out to do when writing this interpreter &#8211; that is to push haXe, Flash, and JavaScript to the limit and see what i can get out of them. And of course, learn a bit more about <span class='caps'>SCUMM</span> too.</p><p>Again, i would like to congratulate the ScummVM team for their <span class='caps'>SCUMM</span> interpreter and Alban Bedel for his scummc compiler. Without their efforts, i wouldn&#8217;t have had any code or references from which to base my haXe-based <span class='caps'>SCUMM</span> interpreter.</p><p><strong>Edit</strong>: Source code available from <a href='http://github.com/jamesu/hiscumm/tree/master'>github</a>.</p><p><strong>Edit</strong>: No longer crashes in Safari provided you are using Safari 3.1.2 or later.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Yet another RailsCollab demo</title>

		<link>http://www.cuppadev.co.uk/yet-another-railscollab-demo/</link>
		<comments>http://www.cuppadev.co.uk/yet-another-railscollab-demo/#comments</comments>
		<pubDate>Fri, 23 May 2008 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=144</guid>
		<description><![CDATA[<p>Recently i have had another go at tweaking RailsCollab, the pet project of mine (which i have <a href='http://www.cuppadev.co.uk/mtos/mt-search.cgi?search=railscollab&#38;IncludeBlogs=3'>mentioned previously</a>).</p><p>After moving the source repository from <a href='http://subversion.tigris.org'>Subversion</a> to <a href='http://git.or.cz/'>Git</a>, i decided to add in a long standing missing feature &#8211; the web-based configuration editor.</p><p style='text-align:left;'><a href='http://www.cuppadev.co.uk/assets/rc_cnf.jpg'><img alt='Configuration Editor' src='http://www.cuppadev.co.uk/assets/rc_cnf_th.jpg' title='Configuration Editor' /></a></p><p>Originally i pretty much stayed away from implementing this as <a href='http://www.rubyonrails.org/'>Ruby on Rails</a> was a real pain in the ass when it came to deployment, so i couldn&#8217;t implement a configuration loader that i knew would work in 90% of deployment cases.</p><p>That was, until recently when <a...]]></description>
		<content:encoded><![CDATA[<p>Recently i have had another go at tweaking RailsCollab, the pet project of mine (which i have <a href='http://www.cuppadev.co.uk/mtos/mt-search.cgi?search=railscollab&#38;IncludeBlogs=3'>mentioned previously</a>).</p><p>After moving the source repository from <a href='http://subversion.tigris.org'>Subversion</a> to <a href='http://git.or.cz/'>Git</a>, i decided to add in a long standing missing feature &#8211; the web-based configuration editor.</p><p style='text-align:left;'><a href='http://www.cuppadev.co.uk/assets/rc_cnf.jpg'><img alt='Configuration Editor' src='http://www.cuppadev.co.uk/assets/rc_cnf_th.jpg' title='Configuration Editor' /></a></p><p>Originally i pretty much stayed away from implementing this as <a href='http://www.rubyonrails.org/'>Ruby on Rails</a> was a real pain in the ass when it came to deployment, so i couldn&#8217;t implement a configuration loader that i knew would work in 90% of deployment cases.</p><p>That was, until recently when <a href='http://www.modrails.com/'>Phusion Passenger</a> was released.</p><p style='text-align:left;'><img alt='Phusion Logo' src='http://www.cuppadev.co.uk/assets/phusion-thumb-240x240.png' title='Phusion Logo' /></p><p>For those of you that don&#8217;t know, Passenger is an Apache module which allows you to simply drop in your Rails application and run it with practically zero configuration. It pretty much falls under the &#8220;it just works&#8221; category. I have no doubt that anyone using RailsCollab will prefer using Passenger to deploy. Consequently, i have been able to implement a rather nice configuration loader based on this assumption.</p><p>Which brings me to the demo. A short while back, my web host, <a href='http://dreamhost.com/'>DreamHost</a> added Phusion Passenger support to their web servers. Factor everything together, and you have&#8230; the RailsCollab demo!</p><p><a href='http://freshbrew.cuppadev.co.uk'>Link to the demo</a></p><p>&#8220;But wait!&#8221; you ask, &#8220;how do i login?&#8221;. Well, using <a href='http://openid.net/'>OpenID</a> of course. As with my <a href='http://www.cuppadev.co.uk/2007/08/12/railscollab-demo/'>previous demo</a>,  you should be able to select the &#8220;Use OpenID&#8221; checkbox and type in your OpenID to login.</p><p style='text-align:left;'><img alt='OpenID Logo' src='http://www.cuppadev.co.uk/assets/2007/8/11/openid.png' title='OpenID Logo' /></p><p>This will automagically register you with the system, adding you to the &#8220;OpenID&#8221; company and the &#8220;RailsCollab&#8221; project. Afterwards if you want, you can reset your password so you can login using a regular username &#38; password, though personally i think typing in your OpenID is a better idea.</p><p>Note that your OpenID provider needs to support handing over identity fields in order for RailsCollab to correctly register you. <a href='http://www.myopenid.com'>MyOpenID</a> is an example of a provider that supports this. Also note that if there is a user with a duplicate username or email in the system, registration will fail.</p><h3>One more thing</h3><p>The RailsCollab demo also supports the <a href='http://www.basecamphq.com/'>Basecamp</a> API. This means that you can take any existing widget, program, or service that <a href='http://basecamphq.com/extras'>integrates with Basecamp</a> and <strong>use it with RailsCollab</strong>. e.g. <a href='http://www.avalanche-widget.org/'>Avalanche</a>, <a href='http://www.freshbooks.com/'>Freshbooks</a>, or <a href='http://www.getcashboard.com/'>Cashboard</a></p><p>So what are you waiting for? <a href='http://freshbrew.cuppadev.co.uk'>Try the demo already!:</a> :)</p>]]></content:encoded>
	</item>
	
	<item>
		<title>An Analogue Clock using Safari Transforms</title>

		<link>http://www.cuppadev.co.uk/an-analogue-clock-using-safari-transforms/</link>
		<comments>http://www.cuppadev.co.uk/an-analogue-clock-using-safari-transforms/#comments</comments>
		<pubDate>Thu, 20 Mar 2008 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=141</guid>
		<description><![CDATA[<p>Recently <a href='http://www.apple.com/safari'>Safari 3.1</a> has been released for Mac and Windows, boasting a whole load of useful new features. One of these is support for <a href='http://webkit.org/blog/130/css-transforms/'><span class='caps'>CSS</span> transforms</a> &#8211; i.e. you can translate, scale, and rotate <span class='caps'>HTML</span> elements in a web page.</p><p><span class='caps'>CSS</span> transforms can come in quite handy for making complex dynamic objects, without the need for 3rd party plugins or applets. For example i was able to make the following <span class='caps'>BBC</span>-esque analogue clock, using only <span class='caps'>DIV</span>&#8217;s and JavaScript :</p><strong>(Note that currently this only works in Safari 3.1)</strong><iframe frameborder='0' height='132' src='http://www.cuppadev.co.uk/assets/test.html' width='132'><!-- --></iframe> <p><em>EDIT:</em> Now...]]></description>
		<content:encoded><![CDATA[<p>Recently <a href='http://www.apple.com/safari'>Safari 3.1</a> has been released for Mac and Windows, boasting a whole load of useful new features. One of these is support for <a href='http://webkit.org/blog/130/css-transforms/'><span class='caps'>CSS</span> transforms</a> &#8211; i.e. you can translate, scale, and rotate <span class='caps'>HTML</span> elements in a web page.</p><p><span class='caps'>CSS</span> transforms can come in quite handy for making complex dynamic objects, without the need for 3rd party plugins or applets. For example i was able to make the following <span class='caps'>BBC</span>-esque analogue clock, using only <span class='caps'>DIV</span>&#8217;s and JavaScript :</p><strong>(Note that currently this only works in Safari 3.1)</strong><iframe frameborder='0' height='132' src='http://www.cuppadev.co.uk/assets/test.html' width='132'><!-- --></iframe>
<p><em>EDIT:</em> Now works in FireFox too!</p>
<p>Yes, <span class='caps'>DIV</span>&#8217;s and JavaScript. No Canvas, no Flash, no SilverLight, no Java Applets, no Plugins.</p><p>It makes me wonder, considering that browsers seem to be getting so powerful nowadays, should one really bother using Flash &#38; co anymore?</p>]]></content:encoded>
	</item>
	
	<item>
		<title>What not to write in haXe, Part II</title>

		<link>http://www.cuppadev.co.uk/what-not-to-write-in-haxe-part-ii/</link>
		<comments>http://www.cuppadev.co.uk/what-not-to-write-in-haxe-part-ii/#comments</comments>
		<pubDate>Fri, 07 Mar 2008 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=140</guid>
		<description><![CDATA[<p>I decided to have another go at writing some awe-inspiring haXe code again. This time, i picked up from where <a href='http://www.cuppadev.co.uk/2008/01/27/what-not-to-write-in-haxe/'>i left off</a> &#8211; that was trying to get my infamous <a href='http://www.cuppadev.co.uk/2007/11/22/flash-plays-scumm-take-two/'><span class='caps'>SCUMM</span> interpreter</a> working on additional platforms which haXe supports.</p><p>For reference, i concentrated on getting it to work on the <a href='http://www.nekovm.org'>neko</a> platform.</p><p>To start off with, i took notice of a suggestion to simplify the import statements which littered the top of the source code. So instead of this:</p> <pre><code>#if flash9 import flash.display.Bitmap; ... #else neko import noflash.Bitmap; ... #end</code></pre> <p>I consolidated everything into a single file...]]></description>
		<content:encoded><![CDATA[<p>I decided to have another go at writing some awe-inspiring haXe code again. This time, i picked up from where <a href='http://www.cuppadev.co.uk/2008/01/27/what-not-to-write-in-haxe/'>i left off</a> &#8211; that was trying to get my infamous <a href='http://www.cuppadev.co.uk/2007/11/22/flash-plays-scumm-take-two/'><span class='caps'>SCUMM</span> interpreter</a> working on additional platforms which haXe supports.</p><p>For reference, i concentrated on getting it to work on the <a href='http://www.nekovm.org'>neko</a> platform.</p><p>To start off with, i took notice of a suggestion to simplify the import statements which littered the top of the source code. So instead of this:</p>
<pre><code>#if flash9
import flash.display.Bitmap;
...
#else neko
import noflash.Bitmap;
...
#end</code></pre>
<p>I consolidated everything into a single file which looked like this:</p>
<pre><code>#if flash9
typedef Bitmap = flash.display.Bitmap;
...
#else neko
typedef ByteArray = noflash.ByteArray;
...
#end</code></pre>
<p>So when i used &#8220;import hiscumm.Common&#8221;, i could now access all of the classes listed with little fuss!</p><p>Another change i made was to re-factor the way resources were loaded. Before, i just used flash 9&#8217;s ByteArray. However as there is no direct equivalent of this on the neko platform, i had to implement my own.</p><p>Thinking more, i determined that only a relatively small portion of my code actually needed to use all of the features of ByteArray, so instead i changed all of the IO code to use the neko api&#8217;s Input &#38; Output classes.</p><p>Finally i made all 32bit integers Int32&#8217;s. Consequently, i had to re-implement the Int32 class for the flash platform, but all things considered it was the best solution.</p><h3>Problems</h3><p>As before, i ran into a fair share of problems. Most were minor, and others were solved when i upgraded from haXe 1.17 to 1.18. Here are some of the more notable ones i came across.</p><p><strong>&#8220;No arrays larger than 115 elements&#8221;</strong></p><p>I ended up finding a rather obvious solution to this problem which worked transparently with the other platforms. All one has to do is split up the troublesome array into several smaller arrays and then concatenate them together. e.g.</p>
<pre><code>var longarray = [1,2,3].concat([4,5,6]).concat(7,8,9); // works</code></pre>
<p>Problem solved.</p><p><strong>&#8220;Beware of classes extending Int&#8221;</strong></p><p>In an earlier implementation of my Int32 class, i had it extending Int. This turned out to be a fatal mistake, as when i tested out the code absolutely nothing worked.</p><p>The solution of course was just to not extend from Int.</p><p><strong>&#8220;haxe.Timer does not have a constructor&#8221;</strong></p><p>I kept getting a rather odd compile error. It seemed that no constructor was defined for the Timer class, which i used to run the game loop. This was very odd, as the <span class='caps'>API</span> documentation didn&#8217;t state anything unusual about the Timer class on the neko platform.</p><p>However after checking out the code to the Timer, i soon came to realise the horrifying truth: the Timer class wasn&#8217;t implemented for the neko platform. Arrrgh! I got this far and now i&#8217;m stopped by something as simple as this?</p><p>Thankfully i figured out a rather obvious workaround. Instead of using the timer, i merely made a typical run-of-the-mill game loop. Problem solved.</p>
<pre><code>while (true)
{
  onTime();
  neko.Sys.sleep(0.01);
}</code></pre>
<h3>The result</h3><p>As the output below shows, the interpreter now actually runs on neko. Unfortunately there appears to be a rather nasty bug when decoding the room image. But then again i&#8217;ve not implemented any video code for the neko platform yet, so the usefulness of this is questionable to say the least.</p>
<pre><code>$ neko test.n
NekoTest.hx:42: Engine init
SCUMM.hx:486: boot state
SPUTMResource.hx:308: Loading resource 1 from file 1, room 2 (SCRIPT)
SCUMM.hx:488: Started
SCUMM6.hx:1249: ARRAY = &quot;&quot; 
SCUMM6.hx:1249: ARRAY = &quot;ScummC Paused !&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Are you sure you want to quit ? (Y/N)Y&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Are you sure you want to restart ? (Y/N)Y&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Save it&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Load it&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Continue&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Cancel&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Quit&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Ok&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Saveing &#39;%s&#39;&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Loading &#39;%s&#39;&quot; 
SCUMM6.hx:1249: ARRAY = &quot;ScummC test Menu&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Save game&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Load game&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Game NOT saved&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Game NOT loaded&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Insert disk %c&quot; 
SCUMM6.hx:1249: ARRAY = &quot;You must enter a name&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Insert your save disk&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Failed to open %s (%c%d)&quot; 
SCUMM6.hx:1249: ARRAY = &quot;Read error on disk %c (%c%d)&quot; 
SCUMM6.hx:788: 103, 645
SPUTMResource.hx:308: Loading resource 2 from file 1, room 2 (ROOM)
SPUTMRoom.hx:173: RMIM == RMIM
SPUTMImage.hx:109: smap size == 8
SPUTM.hx:1096: Internal exception, aborting! (state=SPUTM_RUNNING)
SPUTM.hx:1097: &amp;gt;&amp;gt;</code></pre>
<p>As before, the hiscumm code is available for reference. Unlike last time however, the code is now hosted in a git repository so you can now see all the nitty gritty changes i have made to it. Great!</p><p><a href='http://projects.cuppadev.co.uk/gitweb/?p=experiments/hiscumm.git;a=summary'>Click here</a> to check it out!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>What not to write in haXe</title>

		<link>http://www.cuppadev.co.uk/what-not-to-write-in-haxe/</link>
		<comments>http://www.cuppadev.co.uk/what-not-to-write-in-haxe/#comments</comments>
		<pubDate>Sun, 27 Jan 2008 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=139</guid>
		<description><![CDATA[<p>You might have notice that during the past few months i&#8217;ve written a <a href='http://www.cuppadev.co.uk/2008/01/14/a-wiki-written-in-haxe/'>few</a> <a href='http://www.cuppadev.co.uk/2007/11/22/flash-plays-scumm-take-two/'>articles</a> <a href='http://www.cuppadev.co.uk/2007/10/06/flash-plays-scumm-sort-of/'>about</a> <a href='http://www.cuppadev.co.uk/2007/10/04/haxe-web-oriented-universal-language/'>haXe</a>, a language and compiler which pits itself as a &#8220;toolbox for the web developer&#8221;.</p><p>Recently i decided to test out haXe&#8217;s platform support. I did this by taking my <span class='caps'>SCUMM</span> interpreter code &#8211; which i had previously written for flash 9 &#8211; and tried to get it to work on the other two major platforms haXe supports, javascript and neko.</p><p>To start off with, i had to remove its dependency on flash. This was achieved by making replacement classes and...]]></description>
		<content:encoded><![CDATA[<p>You might have notice that during the past few months i&#8217;ve written a <a href='http://www.cuppadev.co.uk/2008/01/14/a-wiki-written-in-haxe/'>few</a> <a href='http://www.cuppadev.co.uk/2007/11/22/flash-plays-scumm-take-two/'>articles</a> <a href='http://www.cuppadev.co.uk/2007/10/06/flash-plays-scumm-sort-of/'>about</a> <a href='http://www.cuppadev.co.uk/2007/10/04/haxe-web-oriented-universal-language/'>haXe</a>, a language and compiler which pits itself as a &#8220;toolbox for the web developer&#8221;.</p><p>Recently i decided to test out haXe&#8217;s platform support. I did this by taking my <span class='caps'>SCUMM</span> interpreter code &#8211; which i had previously written for flash 9 &#8211; and tried to get it to work on the other two major platforms haXe supports, javascript and neko.</p><p>To start off with, i had to remove its dependency on flash. This was achieved by making replacement classes and switching between the two using the conditional pre-processor. i.e.:</p>
<pre><code>#if flash9
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.utils.ByteArray;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.Timer;
import flash.events.TimerEvent;
#else neko
import noflash.ByteArray;
import noflash.Bitmap;
import noflash.BitmapData;
import noflash.Point;
import noflash.Rectangle;
import noflash.Timer;
import noflash.TimerEvent;
#end</code></pre>
<p>Most of the modifications to the code looked like this, with liberal sprinklings of &#8221;#if flash9 &#8230; #end&#8221; round the flash specific code.</p><p>Eventually i got to the point where things started to look like they were going to compile, or <strong>so i thought</strong>...</p><h3>Problems</h3><p><em><strong>&#8220;Array too big&#8221;</strong></em></p><p>The first problem i encountered was that it wouldn&#8217;t compile.</p>
<pre><code>hiscumm/SCUMM6.hx:1870: lines 1870-2127 : This array declaration is too big, try to split it</code></pre>
<p>Array declaration too big? What on earth was it going on about?</p>
<pre><code>| TArrayDecl el -&amp;gt;
if List.length el &amp;gt; 115 then error &quot;This array declaration is too big, try to split it&quot; e.epos;
call p (field p (ident p &quot;Array&quot;) &quot;new1&quot;) [array p (List.map (gen_expr ctx) el); int p (List.length el)]</code></pre>
<p>Oh, right. Seems i cannot have arrays declared with more than <strong>115 elements</strong>. A seemingly arbitrary limitation that is not referenced anywhere in the documentation &#8211; great!</p><p>Not needing the opcode table for my little experiment, i commented most of it out. Problem solved.</p><p><strong>&#8220;32bit? no, 31bit!&#8221;</strong></p><p>Now the first time i got the interpreter to compile for neko, i thought &#8220;Wow, great! Looks like this is going to work.&#8221; Unfortunately though, it didn&#8217;t. Instead, i got a rather odd exception when reading out of my replacement ByteArray:</p><pre>
<code>
Uncaught exception - Overflow
</code>
</pre><p>Turns out the problem was with this code here, in neko.Input:</p><pre>
<code>
	public function readInt32() {
	  var ch1 = readChar();
	  var ch2 = readChar();
	  var ch3 = readChar();
	  var ch4 = readChar();
	  if( (ch4 &#38; 128) != 0 ) {
	    if( ch4 &#38; 64 == 0 ) throw Error.Overflow;
	    return ch1 | (ch2 &lt;&lt; 8) | (ch3 &lt;&lt; 16) | ((ch4 &#38; 127) &lt;&lt; 24);
	  } else {
	    if( ch4 &#38; 64 != 0 ) throw Error.Overflow;
	    return ch1 | (ch2 &lt;&lt; 8) | (ch3 &lt;&lt; 16) | (ch4 &lt;&lt; 24);
	  }
	}
</code>
</pre><p>So basically the reader was trying to stuff the whole <strong>32 bit value</strong> into a neko Integer, which is actually <strong>31 bits</strong>. Oddly enough though, the value being read was identical to a value i specified in the code.</p><p>But haXe never bothered to complain about an <strong>overflow</strong>!</p><p>This can be demonstrated by the following code, which prints &#8220;-766623411&#8221; instead of the expected &#8220;1380860237&#8221;.</p>
<pre><code>trace(1380860237);</code></pre>
<p>Thankfully, a solution exists. There is an &#8220;Int32&#8221; type which properly handles 32bit integers. However there is a really big snag with it &#8211; it&#8217;s a <strong>class</strong>.</p><p>That means you cannot use any fancy inbuilt operators with it &#8211; you have to use a set of functions instead.</p>
<pre><code>import neko.Int32;

var result: Int = 1 + 2; // simple
var result32: Int32 = Int32.add(Int32.ofInt(1), Int32.ofInt(2)); // aaaarrrghh!!!

result += 1; // simple
result32 += 1; // don&#39;t even think about it, it won&#39;t work</code></pre>
<p>And to top it all off, this &#8220;Int32&#8221; class only exists for the neko platform, you cannot use it with flash or javascript. Unless you write it yourself, but that is besides the point. It should at least have been there to fill in the gap.</p><h3>Conclusion</h3><p>If you are looking at writing code in haXe and want it to work across all 3 of its supported platforms (flash*, neko and javascript), then beware if you are reading, writing, or otherwise processing 32bit integers.</p><p>In addition watch out for mysterious arbitrary limitations such as the 115 item limit for declared arrays.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Accounting with Luca</title>

		<link>http://www.cuppadev.co.uk/accounting-with-luca/</link>
		<comments>http://www.cuppadev.co.uk/accounting-with-luca/#comments</comments>
		<pubDate>Thu, 03 Jan 2008 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=137</guid>
		<description><![CDATA[<p>A while ago now, i stumbled across a web based double entry accounting solution called <a href='http://epx.com.br/luca/index.php'>Luca</a> (not to be confused with the <a href='http://cutedgesystems.com/software/luca'>Mac Application</a>).</p><p>Unfortunately though, the documentation was a bit sparse. However with a bit of persistence, i have just about managed to figure out how to use it.</p><h3>Starting out</h3><p><em>(note that for this little walkthrough i am using Luca 1.02, so don&#8217;t be surprised if you are using a later version and things look that bit different)</em></p><p>Assuming you have managed to download and install Luca, as well as log in, you&#8217;ll be presented with this rather interesting interface:</p><p...]]></description>
		<content:encoded><![CDATA[<p>A while ago now, i stumbled across a web based double entry accounting solution called <a href='http://epx.com.br/luca/index.php'>Luca</a> (not to be confused with the <a href='http://cutedgesystems.com/software/luca'>Mac Application</a>).</p><p>Unfortunately though, the documentation was a bit sparse. However with a bit of persistence, i have just about managed to figure out how to use it.</p><h3>Starting out</h3><p><em>(note that for this little walkthrough i am using Luca 1.02, so don&#8217;t be surprised if you are using a later version and things look that bit different)</em></p><p>Assuming you have managed to download and install Luca, as well as log in, you&#8217;ll be presented with this rather interesting interface:</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/luca_main.png'><img alt='Luca main menu' src='http://www.cuppadev.co.uk/assets/luca_main_th.jpg' title='Luca main menu' /></a></p><p>Whoah! Lots of options to choose from, but which of those do we need to start off with?</p><p>First things first, you&#8217;ll need to create a chart of accounts, so select the &#8220;Charts of accounts&#8221; option. You&#8217;ll be presented with a list of charts, which should be empty. Click on &#8220;Add new chart&#8221;, and your screen will look something like this:</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/luca_chart_new.png'><img alt='Luca new chart' src='http://www.cuppadev.co.uk/assets/luca_chart_new_th.jpg' title='Luca new chart' /></a></p><p>The only 2 values which are of interest are &#8220;Description&#8221; and &#8220;Format mask&#8221;, the former of which can be anything you like. The latter is a bit more tricky, and it took me a while to figure out. It seems that the &#8220;Format mask&#8221; is basically a sequence of 9&#8217;s using dots as separators. The more dots you use, the more you can nest your accounts.</p><p>For reference, i put the following values in this form:</p><ul>
<li>Description: LucaCorp</li>
<li>Format Mask: 9999.99 (i.e. 2 levels one using four digits, the other using two)</li>
</ul><p>You should now have a chart you can use. But to be of any use, it needs to be assigned to an Organization. To do this, go back to the main menu, and select &#8220;Organizations&#8221;. Then select &#8220;Add new Organization&#8221;. Your screen should now look something like this:</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/luca_new_org.png'><img alt='Luca new organization' src='http://www.cuppadev.co.uk/assets/luca_new_org_th.jpg' title='Luca new organization' /></a></p><p>Give your Organization a name, a remark if you like, and of course a chart of accounts. The values i used are as follows:</p><ul>
<li>Name: LucaCorp</li>
<li>Remarks: <strong>blank</strong></li>
<li>Chart of Accounts: LucaCorp</li>
</ul><p>Note that you will also need to give yourself (and anyone else you trust with a user account) permission to use the Organization when entering transactions. This can be done in the &#8220;Users X Organizations&#8221; screen.</p><h3>Creating accounts</h3><p>Now would be a good idea to actually make some accounts. To do this, go back to the main menu and select &#8220;Accounts of the chart&#8221;. Then for the &#8220;Parent chart being edited:&#8221; field, select your chart of accounts. Your screen should now look something like this:</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/luca_new_account_ch.png'><img alt='Luca add account' src='http://www.cuppadev.co.uk/assets/luca_new_account_ch_th.jpg' title='Luca add account' /></a></p><p>For each account you want to create, click on &#8220;Add Account&#8221; and fill in the form, which should look something like this:</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/luca_new_account.png'><img alt='Luca add account' src='http://www.cuppadev.co.uk/assets/luca_new_account_th.jpg' title='Luca add account' /></a></p><p>The <em>&#8220;Class&#8221;</em> is the type of account to be created. You can make Accounts for Assets, Liabilities, Equity, Revenue, and Expenses (note that this list can be altered by playing about with the &#8220;Account classes&#8221;).</p><p>The <em>&#8220;Std. journal&#8221;</em> corresponds to an id of a &#8220;Standard Journal Description&#8221; which you can make in &#8220;Standard Journal Descriptions&#8221;. From what i can tell this allows you to save on typing repetitive descriptions when entering transactions, though i have not really found a use for it yet.</p><p><em>&#8220;Code&#8221;</em> is the identifier of this account. It needs to correspond to the <em>&#8220;Format Mask&#8221;</em> you created earlier, e.g. in my case, &#8220;1234&#8221; and &#8220;1234.01&#8221; would both be acceptable.</p><p><em>&#8220;Parent account&#8221;</em> is the code of the account you wish to be the parent. You can use this to create complex hierarchies of accounts, something which i assume Accountants love to do.</p><p>The rest of the fields are pretty obvious, apart from <em>&#8220;Mobile clients&#8221;</em> which i can only assume allows people using Luca&#8217;s bluetooth functionality to enter transactions on the account (note though that i have not tried this out).</p><p>So now you can create accounts at will. As for which accounts to create, it&#8217;s really up to you. However if you are a bit stuck, below is a table of values you can enter to reproduce a set of accounts from of one of my <a href='http://www.austintek.com/gnucash/ncsa-gnucash-talk.html'>favourite tutorials</a> on Double Entry Accounting written by Joseph Mack.</p><p><em>RocketScience <span class='caps'>LLC</span> Accounts</em></p><table style='border-collapse: separate;border-spacing: 4px 2px;'>
<tr>
<th>Class</th>
<th>Code</th>
<th>Parent</th>
<th>Description</th>
<th>Small description</th>
</tr>
<tr>
<td>Asset</td>
<td>1234 </td>
<td>cash</td>
<td>cash</td>
</tr>
<tr>
<td>Asset</td>
<td>1234.01 </td>
<td>1234</td>
<td>Joseph Mack, withdrawing</td>
<td>jm_withdrawing</td>
</tr>
<tr>
<td>Asset</td>
<td>1234.02 </td>
<td>1234</td>
<td>check account</td>
<td>check_account</td>
</tr>
<tr>
<td>Asset</td>
<td>1234.03 </td>
<td>1234</td>
<td>petty cash</td>
<td>petty_cash</td>
</tr>
<tr>
<td>Liabilities</td>
<td>1235 </td>
<td>liabilities</td>
<td>liabilities</td>
</tr>
<tr>
<td>Liabilities</td>
<td>1235.01 </td>
<td>1235</td>
<td>Joseph Mac, capital</td>
<td>jm_capital</td>
</tr>
<tr>
<td>Equity</td>
<td>1236 </td>
<td>equity</td>
<td>equity</td>
</tr>
<tr>
<td>Equity</td>
<td>1236.01 </td>
<td>1236</td>
<td>accumulated profit and loss</td>
<td>acc_profit_loss</td>
</tr>
<tr>
<td>Equity</td>
<td>1236.02 </td>
<td>1236</td>
<td>[clo]profit and loss</td>
<td>profit_loss</td>
</tr>
<tr>
<td>Revenue</td>
<td>1237 </td>
<td>revenue</td>
<td>revenue</td>
</tr>
<tr>
<td>Revenue</td>
<td>1237.01 </td>
<td>1237</td>
<td>fees earned</td>
<td>fees_earned</td>
</tr>
<tr>
<td>Expenses</td>
<td>1238 </td>
<td>expenses</td>
<td>expenses</td>
</tr>
<tr>
<td>Expenses</td>
<td>1238.01 </td>
<td>1238</td>
<td>advertising</td>
<td>advertising</td>
</tr>
<tr>
<td>Expenses</td>
<td>1238.02 </td>
<td>1238</td>
<td>food,entertainment</td>
<td>food_entertainment</td>
</tr>
<tr>
<td>Expenses</td>
<td>1238.03 </td>
<td>1238</td>
<td>office supplies</td>
<td>office_supplies</td>
</tr>
</table><h3>Entering transactions</h3><p>To enter transactions in Luca, you&#8217;ll need to first create a Batch. To do this, from the main menu select &#8220;Batches&#8221;. Then on the next screen, select your Organization and click on &#8220;Add new batch&#8221;. Your screen should look something like this:</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/luca_new_batch.png'><img alt='Luca add batch' src='http://www.cuppadev.co.uk/assets/luca_new_batch_th.jpg' title='Luca add batch' /></a></p><p>As you might have noticed, there is not much to a batch. The only thing to look out for is the dates you enter, which need to be in the format &#8220;yyyy/mm/dd&#8221;, and need to lie within the organization&#8217;s active period (the default being 1970/01/01 -&gt; 1970/01/01).</p><p>If you ever want to change the date range of the active period, all you need to do is select &#8220;Active Period&#8221; from the main menu, then click on &#8220;Edit&#8221; next to the relevant accounting period for your organization. Your screen should look something like this:</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/luca_edit_period.png'><img alt='Luca edit accounting period' src='http://www.cuppadev.co.uk/assets/luca_edit_period_th.jpg' title='Luca edit accounting period' /></a></p><p>Then all you need to do is enter an initial and final date. It&#8217;s as simple as that!</p><p>For my first batch, i used the following:</p><ul>
<li>Description: First batch!</li>
<li>Initial date: 1970/01/01</li>
<li>Final date: 1970/01/01</li>
<li>Checksum: 0</li>
<li>Status: Open</li>
<li>Type: Normal batch</li>
</ul><p>Now you can start entering your transactions, which in Luca are referred to as <em>Journals</em>. To do this, from the main menu select &#8220;Journals&#8221;. Then on the next screen, select your Organization and Batch, then click on &#8220;Add new journal&#8221;. Your screen should look something like this:</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/luca_new_journal.png'><img alt='Luca add journal' src='http://www.cuppadev.co.uk/assets/luca_new_journal_th.jpg' title='Luca add journal' /></a></p><p>So to sum this up&#8230;</p><p><em>&#8220;DB account&#8221;</em> and <em>&#8220;CR account&#8221;</em> mean <em>&#8220;Account to debit&#8221;</em> and <em>&#8220;Account to credit&#8221;</em> respectively. I&#8217;m going to assume you know enough about double entry accounting to figure out which accounts you credit and which you debit.</p><p><em>&#8220;Std. journal&#8221;</em> i already mentioned when creating accounts.</p><p><em>&#8220;Cost center&#8221;</em> i have yet to figure out, best to leave this as 1 unless you really need it set.</p><p><em>&#8220;Date&#8221;</em>, <em>&#8220;Description&#8221;</em>, <em>&#8220;Value&#8221;</em>, and <em>&#8220;Status&#8221;</em> are all pretty obvious.</p><p>You can enter as many journals as you like in a batch. It is also interesting to note that you don&#8217;t have to enter both a credit and debit for an entry &#8211; you can quite easily add multiple debit or credits in a row.</p><h3>Profit and Loss</h3><p>At the end of the accounting year, you&#8217;ll probably want to determine profit and loss, which usually involves folding revenue and expense accounts into a single profit and loss account. This is otherwise known as &#8220;closing out the accounts&#8221;.</p><p>So how does one do this in Luca? Quite simply in fact. Select &#8220;Balance closing&#8221; from the main menu, and your screen should look something like this:</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/luca_close_balance.png'><img alt='Luca closing balance' src='http://www.cuppadev.co.uk/assets/luca_close_balance_th.jpg' title='Luca closing balance' /></a></p><p>So basically all you need to do is select your organization, enter in start and end dates, then click &#8220;Prepare to close balance&#8221;.</p><p>However you&#8217;ll probably bump into a few issues first time, as three conditions need to be satisfied:</p><ol>
<li>You need an account which contains &#8220;[clo]&#8221; somewhere in its description to store the closing values.</li>
<li>The period you specify needs to be within the current active period.</li>
<li>All batches in the specified period need to be set to &#8220;Closed&#8221;</li>
</ol><p>The first condition is rather easy to satisfy. All you need to do is make an equity account named something like &#8220;[clo]Profit and Loss&#8221;.</p><p>The last two conditions we more or less went over when talking about batches.</p><p>Assuming you got the balance to close, your &#8220;Profit and Loss&#8221; equity account should now look something like this:</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/luca_profit_loss.png'><img alt='Luca profit and loss ledger' src='http://www.cuppadev.co.uk/assets/luca_profit_loss_th.jpg' title='Luca profit and loss ledger' /></a></p><h3>To sum it all up</h3><p>Luca is a pretty promising accounting solution. It does accounting, reports, and also includes a bit of multiuser management too. In contrast to other solutions, it doesn&#8217;t try to do everything &#8211; which i believe is one of its strengths. It&#8217;s a relief not having to wade through a swamp of <span class='caps'>CRM</span> to do something as simple as sorting out the accounts.</p><p>Sadly though Luca doesn&#8217;t appear to have a very active community, and from what i can tell Elvis Pfützenreuter puts most of the work into it.</p><p>Still from what i have been able to gather Luca is still under development so with any luck it&#8217;ll gain more useful features in the future such as multiple currency support.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>RailsCollab on Rails 2.0</title>

		<link>http://www.cuppadev.co.uk/railscollab-on-rails-20/</link>
		<comments>http://www.cuppadev.co.uk/railscollab-on-rails-20/#comments</comments>
		<pubDate>Sat, 08 Dec 2007 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=134</guid>
		<description><![CDATA[<p>Soon after hearing that version 2.0 of the Ruby on Rails web development framework had been released, i decided to try out my pet project <a href='http://railscollab.rubyforge.org'>RailsCollab</a> to see if it would work properly in the new release.</p><p>Sadly it did not, though it didn&#8217;t take too long to fix everything. To summarise:</p><ol> <li>I still used a few deprecated functions and parameters, such as link_to_url, @request, start_form_tag, and so on. Changing references to their new counterparts solved this issue.</li> <li>Two plugins i use, &#8220;enum-column&#8221; and &#8220;paginating_find&#8221; broke. I had to modify the code for these as illustrated below.</li> <li>A new script,...]]></description>
		<content:encoded><![CDATA[<p>Soon after hearing that version 2.0 of the Ruby on Rails web development framework had been released, i decided to try out my pet project <a href='http://railscollab.rubyforge.org'>RailsCollab</a> to see if it would work properly in the new release.</p><p>Sadly it did not, though it didn&#8217;t take too long to fix everything. To summarise:</p><ol>
<li>I still used a few deprecated functions and parameters, such as link_to_url, @request, start_form_tag, and so on. Changing references to their new counterparts solved this issue.</li>
<li>Two plugins i use, &#8220;enum-column&#8221; and &#8220;paginating_find&#8221; broke. I had to modify the code for these as illustrated below.</li>
<li>A new script, &#8220;script/performance/request&#8221; was added to i naturally had to add it to my svn repository</li>
<li>The default session container changed to cookies, so i had to fill in &#8220;config.action_controller.session&#8221; in config/environment.rb</li>
<li>&#8220;config.breakpoint_server = true&#8221; had to be removed from my development environment</li>
<li>Mongrel decided to through a wobbler and stop working, so i had to do a reinstall of it</li>
</ol><h3>How to update</h3><p>Initially i was a bit confused regarding the correct update procedure, however i believe the following commands should suffice:</p>
<pre><code>sudo gem update rails -y

# In your app&#39;s directory
rake rails:update</code></pre>
<h3>enum-column fix</h3><p>Since database plugins for Rails have been seperated from the core, enum-column runs into a bit of trouble as it assumes the plugins for MySQL and PostgreSQL are loaded when in most cases they are not.</p><p>In addition i couldn&#8217;t even get the PostgreSQL plugin working, though this wasn&#8217;t so much an issue as i only use the plugin to support the initial database schema from ActiveCollab.</p><p>So in &#8220;vendor/plugins/enum-column/plugins/enum-column/init.rb&#8221;, change the following:</p>
<pre><code>require &#39;enum/mysql_adapter&#39;
require &#39;enum/postgresql_adapter&#39;</code></pre>
<p>To this:</p>
<pre><code>require &#39;enum/mysql_adapter&#39; if (ActiveRecord::ConnectionAdapters.const_defined? :MysqlAdapter)
# require &#39;enum/postgresql_adapter&#39;</code></pre>
<h3>paginating_find fix</h3><p>This one is rather simple. In &#8220;vendor/plugins/paginating_find/lib/paginating_find.rb&#8221;, look for this line:</p>
<pre><code>options = extract_options_from_args!(args)</code></pre>
<p>And change it to this:</p>
<pre><code>options = args.extract_options!</code></pre>
<h3>Initial impressions</h3><p>I was very impressed to find that RailsCollab was notably faster in development mode. I suspect this is due to a combination of that fancy query caching system and of course the change to cookie-based storage as the default session storage system.</p><p>Apart from the minor hiccups i had when updating RailsCollab, i&#8217;ve not had any more issues with Rails 2.0. For my future projects, i will definitely be targeting Rails 2.0.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Double Entry Accounting in Rails</title>

		<link>http://www.cuppadev.co.uk/double-entry-accounting-in-rails/</link>
		<comments>http://www.cuppadev.co.uk/double-entry-accounting-in-rails/#comments</comments>
		<pubDate>Thu, 06 Dec 2007 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=133</guid>
		<description><![CDATA[<p>The first helpful article i found, <a href='http://homepages.tcp.co.uk/~m-wigley/gc_wp_ded.html'>Double Entry Accounting in a Relational Database</a>, suggests i need at least the following models in my system:</p><ul> <li>Account (has many Postings)</li> <li>Asset Type (e.g. £, $, monkeys)</li> <li>Batch (has many Journals, though not really needed)</li> <li>Journal (has many Postings)</li> <li>Posting (associates with Account, Journal, and Asset Type)</li> </ul><p>However one problem i noticed with the article was that instead of separate "credit" and "debit" fields, everything is consolidated into an "amount" field. This meant that the abstraction between debiting and crediting needed to be handled in the model rather than the actual database.</p><p>Puzzled...]]></description>
		<content:encoded><![CDATA[<p>The first helpful article i found, <a href='http://homepages.tcp.co.uk/~m-wigley/gc_wp_ded.html'>Double Entry Accounting in a Relational Database</a>, suggests i need at least the following models in my system:</p><ul>
<li>Account (has many Postings)</li>
<li>Asset Type (e.g. £, $, monkeys)</li>
<li>Batch (has many Journals, though not really needed)</li>
<li>Journal (has many Postings)</li>
<li>Posting (associates with Account, Journal, and Asset Type)</li>
</ul><p>However one problem i noticed with the article was that instead of separate "credit" and "debit" fields, everything is consolidated into an "amount" field. This meant that the abstraction between debiting and crediting needed to be handled in the model rather than the actual database.</p><p>Puzzled by this, i decided to look at the database schema used in other Accounting products: <a href='http://www.ledgersmb.org/'>LedgerSMB</a> and <a href='http://jgnash.sourceforge.net'>jGnash</a>.</p><p style='text-align:left;'><a href='http://www.ledgersmb.org'><img alt='LedgerSMB Logo' src='http://www.cuppadev.co.uk/assets/2007/12/6/garland_logo.jpg' style='border:none;' title='LedgerSMB Logo' /></a></p><p>LedgerSMB uses a rather complex database schema. I couldn't make much sense of it, apart from like the aforementioned article it consolidated credits and debits into an "amount" field rather than have them as separate fields.</p><p style='text-align:left;'><a href='http://jgnash.sourceforge.net'><img alt='jGnash Logo' src='http://www.cuppadev.co.uk/assets/2007/12/6/Jgnash_logo.png' style='border:none;' title='jGnash Logo' /></a></p><p>jGnash was a bit different as instead of a proper database it uses an <span class='caps'>XML</span> file to store its data. Still, there were a few distinctive elements which are the equivalent of models:</p><ul>
<li>Account (linked to Transaction and CurrencyNode)</li>
<li>SingleEntryTransaction (linked to Account, used to insert money out of thin air)</li>
<li>DoubleEntryTransaction (linked to 2 Accounts 'credit' and 'debit'. Also links with CurrencyNode)</li>
<li>SplitTransaction (used to link multiple SplitEntryTransaction's together to indicate a split transaction)</li>
<li>SplitEntryTransaction (linked to SplitTransaction, otherwise the same as DoubleEntryTransaction)</li>
<li>CurrencyNode (e.g. £, $, giraffes)</li>
</ul><p>Personally i found jGnash's <span class='caps'>XML</span> format needlessly complicated, though much more comprehensible than LedgerSMB's database schema.</p><p>Though really, the approach i liked the best was the one mentioned in the article. It made the most sense, and wasn't needlessly complicated. So i decided to implement it.</p><p>While implementing it however, i became a bit stuck on how to abstract the credit and debit in the Posting entries.</p><p>Whenever i have looked at Double Entry Accounting in the past, i always assumed that when you take money out of one account, you need to put the same amount back into another account. Thus i made this rather mistaken test data:</p>
<pre><code># Begin asset types

gbp = AssetType.new(:name =&amp;gt; &#39;GBP&#39;, :symbol =&amp;gt; &#39;£&#39;)
gbp.save!

# Begin accounts

assets = Account.new(:parent_account =&amp;gt; nil,
:asset_type =&amp;gt; gbp,
:name =&amp;gt; &#39;Assets&#39;,
:account_type =&amp;gt; :asset)
assets.save!
equipment = Account.new(:parent_account =&amp;gt; assets,
:asset_type =&amp;gt; gbp,
:name =&amp;gt; &#39;Equipment&#39;,
:account_type =&amp;gt; :asset)
equipment.save!

liabilities = Account.new(:parent_account =&amp;gt; nil,
:asset_type =&amp;gt; gbp,
:name =&amp;gt; &#39;Liabilities&#39;,
:account_type =&amp;gt; :liability)
liabilities.save!
fred = Account.new(:parent_account =&amp;gt; liabilities,
:asset_type =&amp;gt; gbp,
:name =&amp;gt; &#39;Fred&#39;,
:account_type =&amp;gt; :liability)
fred.save!
george = Account.new(:parent_account =&amp;gt; liabilities,
:asset_type =&amp;gt; gbp,
:name =&amp;gt; &#39;George&#39;,
:account_type =&amp;gt; :liability)
george.save!

# Begin transactions

first_transaction = Journal.new(:transaction_type =&amp;gt; :transfer, :start_date =&amp;gt; Time.now)
first_transaction.save!
Posting.new(:account =&amp;gt; george,
:asset_type =&amp;gt; gbp,
:journal =&amp;gt; first_transaction,
:account_period =&amp;gt; 0,
:description =&amp;gt; &#39;Funding&#39;,
:amount =&amp;gt; -250.00).save!
Posting.new(:account =&amp;gt; equipment,
:asset_type =&amp;gt; gbp,
:journal =&amp;gt; first_transaction,
:account_period =&amp;gt; 0,
:description =&amp;gt; &#39;Funding&#39;,
:amount =&amp;gt; +250.00).save!
first_transaction.end_date = Time.now
first_transaction.save!

second_transaction = Journal.new(:transaction_type =&amp;gt; :transfer, :start_date =&amp;gt; Time.now)
second_transaction.save!
Posting.new(:account =&amp;gt; equipment,
:asset_type =&amp;gt; gbp,
:journal =&amp;gt; second_transaction,
:account_period =&amp;gt; 0,
:description =&amp;gt; &#39;Payback&#39;,
:amount =&amp;gt; -100.00).save!
Posting.new(:account =&amp;gt; george,
:asset_type =&amp;gt; gbp,
:journal =&amp;gt; second_transaction,
:account_period =&amp;gt; 0,
:description =&amp;gt; &#39;Payback&#39;,
:amount =&amp;gt; +100.00).save!
second_transaction.end_date = Time.now
second_transaction.save!

third_transaction = Journal.new(:transaction_type =&amp;gt; :transfer, :start_date =&amp;gt; Time.now)
third_transaction.save!
Posting.new(:account =&amp;gt; fred,
:asset_type =&amp;gt; gbp,
:journal =&amp;gt; third_transaction,
:account_period =&amp;gt; 0,
:description =&amp;gt; &#39;Investment&#39;,
:amount =&amp;gt; -300.00).save!
Posting.new(:account =&amp;gt; equipment,
:asset_type =&amp;gt; gbp,
:journal =&amp;gt; third_transaction,
:account_period =&amp;gt; 0,
:description =&amp;gt; &#39;Investment&#39;,
:amount =&amp;gt; +300.00).save!
third_transaction.end_date = Time.now
third_transaction.save!</code></pre>
<p>Which actually appeared to work fine (as in everything sum'd to 0, and if i ignored the minus then Assets = Liabilities) before i started to delve into what debiting and crediting means in relation to whether or not an account is classed as an <strong>Asset</strong> or a <strong>Liability</strong>.</p><p><em>(Note that to simplify things when i say Asset i could alternatively be meaning Expenses, and when i say Liability i could alternatively be meaning Shareholder Equity or Revenue)</em></p><table>
<tr>
<th>Account</th>
<th>Debit</th>
<th>Credit</th>
</tr>
<tr>
<td>Assets</td>
<td>+</td>
<td>-</td>
</tr>
<tr>
<td>Expenses</td>
<td>+</td>
<td>(-)</td>
</tr>
<tr>
<td>Liabilities</td>
<td>-</td>
<td>+</td>
</tr>
<tr>
<td>Shareholder Equity</td>
<td>-</td>
<td>+</td>
</tr>
<tr>
<td>Revenue</td>
<td>(-)</td>
<td>+</td>
</tr>
</table><p>After applying the logic from the above table (<a href='http://en.wikipedia.org/wiki/Double-entry_bookkeeping_system'>courtesy of Wikipedia</a>), i noticed something rather odd. The credit and debit columns on my printout didn't match. For reference, i was using the following queries to grab the credit and debit amounts for each account.:</p>
<pre><code>credit_amount = Posting.sum(:amount, :conditions =&amp;gt; &quot;amount #{account_type == :asset ? &#39;&amp;lt;&#39; : &#39;&amp;gt;&#39;} 0&quot;)
debit_amount = Posting.sum(:amount, :conditions =&amp;gt; &quot;amount #{account_type == :asset ? &#39;&amp;gt;&#39; : &#39;&amp;lt;&#39;} 0&quot;)</code></pre>
<p>However if i modified the code slightly:</p>
<pre><code>credit_amount = Posting.sum(:amount, :conditions =&amp;gt; &quot;amount &amp;lt; 0&quot;)
debit_amount = Posting.sum(:amount, :conditions =&amp;gt; &quot;amount &amp;gt; 0&quot;)</code></pre>
<p>The credit and debit columns mysteriously matched. So what happened?</p><p>Well i puzzled over this for a while, until i read Wikipedia's article on Double Entry Accounting again. This rather simple summary was very insightful:</p><p><strong>Purchase of a Computer</strong></p><ul>
<li>Debit Computer A/c (Fixed Asset A/c)</li>
<li>Credit Creditors A/c (Liability A/c)</li>
</ul><p><em>(A/c being an abbreviation of "account current")</em></p><p><strong>Paying supplier for the computer</strong></p><ul>
<li>Debit Creditors A/c (Liability A/c) You are reducing a Liability A/c</li>
<li>Credit Bank A/c (Asset A/c) Money going Out, an asset account is being reduced</li>
</ul><p>So in fact all the transactions in my test data should have been <strong>increasing</strong> the amount in the liability accounts rather than <strong>decreasing</strong> it (and vice versa when paying back).</p><p>It makes sense now i think about it. The second approach worked because in effect i flipped the meaning of debit and credit by decreasing the amount in the liability accounts and calling it credit rather than increasing the amount in the liability accounts and calling it credit (and vice versa).</p><p>Now i could just go ahead and fix my test data. But then my amounts would cease to sum up to zero, and i would have to run multiple queries (each for debit and credit) to ensure integrity of the data.</p><p>Thus what i really need to do is make an attribute in the Posting model which stores and retrieves the correct "amount" depending on what type of account it is. Something like this should suffice:</p>
<pre><code>def real_amount
  return self.account.account_type == :asset ? self.amount : -self.amount
end

def real_amount=(val)
  self.amount = self.account.account_type == :asset ? val : -val
end</code></pre>
<p>So to sum it up, the only thing i really have to do with liability accounts to satisfy accounting rules is to subtract when i really mean add, and then flip the balance when calculating it. Confusion eliminated!</p><p>Now lets hope i don't get confused again when i start to think "Did i get this right?".</p><p>Currently i am looking into how i can effectively incorporate business concepts such as Invoices, Taxation, and so on into my little Double Entry Accounting system. So expect to see a "Double Entry Accounting with Invoicing in Rails" post in the near future.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Flash Plays SCUMM, Take Two</title>

		<link>http://www.cuppadev.co.uk/flash-plays-scumm-take-two/</link>
		<comments>http://www.cuppadev.co.uk/flash-plays-scumm-take-two/#comments</comments>
		<pubDate>Thu, 22 Nov 2007 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=132</guid>
		<description><![CDATA[<p>Last month after bumping into <a href='http://www.haxe.org'>haXe</a> and <a href='http://blog.brokenfunction.com/2007/07/20/flash-plays-doom/'>Doomed Online</a>, i somehow got the strange idea that i could <a href='http://cuppadev.co.uk/2007/10/06/flash-plays-scumm-sort-of/'>get flash to play <span class='caps'>SCUMM</span> games</a>, like ScummVM.</p><p>While i did get it working as a proof of concept, there was a really off-putting bug in the image decode routines which meant that any displayed room graphics were a jumbled mess.</p><p>Recently though i decided to do a bit of intensive debugging to try and solve the problem. To sum it up, after:</p><ul> <li><a href='http://www.digitalflipbook.com/archives/2005/07/trace_from_the.php'>Turning on the trace output</a> in the Flash debug player</li> <li>Telling scvm and hiscumm to dump...]]></description>
		<content:encoded><![CDATA[<p>Last month after bumping into <a href='http://www.haxe.org'>haXe</a> and <a href='http://blog.brokenfunction.com/2007/07/20/flash-plays-doom/'>Doomed Online</a>, i somehow got the strange idea that i could <a href='http://cuppadev.co.uk/2007/10/06/flash-plays-scumm-sort-of/'>get flash to play <span class='caps'>SCUMM</span> games</a>, like ScummVM.</p><p>While i did get it working as a proof of concept, there was a really off-putting bug in the image decode routines which meant that any displayed room graphics were a jumbled mess.</p><p>Recently though i decided to do a bit of intensive debugging to try and solve the problem. To sum it up, after:</p><ul>
<li><a href='http://www.digitalflipbook.com/archives/2005/07/trace_from_the.php'>Turning on the trace output</a> in the Flash debug player</li>
<li>Telling scvm and hiscumm to dump crucial info their trace logs</li>
<li>Comparing the output of scvm and hiscumm using diff to see where the differences were</li>
<li>Modifying the trace output to pinpoint the problem while <a href='http://www.antunkarlovac.com/blog/?p=56'>dealing with script timeout errors</a>.</li>
</ul><p>I managed to fix the decode routines. Now instead of a jumbled mess like this:</p><p style='text-align:center;'><img alt='Before, courtesy of Albans Road example' src='http://cuppadev.co.uk/assets/2007/10/6/hiscumm-ex.png' title='Before, courtesy of Albans Road example' /></p><p>You get something more like this:</p><p style='text-align:center;'><img alt='After, courtesy of OpenQuest' src='http://cuppadev.co.uk/assets/2007/11/20/hiscumm-rmin-fix.png' title='After, courtesy of OpenQuest' /></p><p>Which safe to say is much nicer to look at. It&#8217;s also as far as i am willing to go with this <span class='caps'>SCUMM</span> implementation.</p><p>With a lot of work put into it, i&#8217;m sure it could run <a href='http://en.wikipedia.org/wiki/Day_of_the_Tentacle'>Day of the Tentacle</a> or <a href='http://en.wikipedia.org/wiki/Sam_%26_Max_Hit_the_Road'>Sam N Max Hit the Road</a>. But there would not be much sense in doing that, except for that 5 seconds of awe after seeing it running in a web browser.</p><p>As previously, you can download the hiscumm code for reference <a href='http://cuppadev.co.uk/assets/2007/11/22/hiscumm.tar.gz'>here</a>.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>RailsCollab Prodding</title>

		<link>http://www.cuppadev.co.uk/railscollab-prodding/</link>
		<comments>http://www.cuppadev.co.uk/railscollab-prodding/#comments</comments>
		<pubDate>Sun, 18 Nov 2007 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=131</guid>
		<description><![CDATA[<p>In my quest to learn the <a href='http://www.rubyonrails.com'>Ruby on Rails</a> (a web development framework), i re-writ a <span class='caps'>PHP</span>-based project management app (ActiveCollab) in it. In fact, i <a href='http://cuppadev.co.uk/2007/6/22/cloning-activecollab'>wrote about all of this</a> a few months ago.</p><p>Now i&#8217;ve had my ups and downs with RailsCollab. The biggest down being that there is little interest in it, especially compared to alternate solutions such as <a href='http://www.projectpier.org'>ProjectPier</a>. Which is unfortunate.</p><p>In any case, a little problem i noticed recently was that RailsCollab still wasn&#8217;t really finished. There were still numerous bugs and missing features which made it feel more of a hack...]]></description>
		<content:encoded><![CDATA[<p>In my quest to learn the <a href='http://www.rubyonrails.com'>Ruby on Rails</a> (a web development framework), i re-writ a <span class='caps'>PHP</span>-based project management app (ActiveCollab) in it. In fact, i <a href='http://cuppadev.co.uk/2007/6/22/cloning-activecollab'>wrote about all of this</a> a few months ago.</p><p>Now i&#8217;ve had my ups and downs with RailsCollab. The biggest down being that there is little interest in it, especially compared to alternate solutions such as <a href='http://www.projectpier.org'>ProjectPier</a>. Which is unfortunate.</p><p>In any case, a little problem i noticed recently was that RailsCollab still wasn&#8217;t really finished. There were still numerous bugs and missing features which made it feel more of a hack than a real product.</p><p>So i set aside some of my spare time to fix it. After a few days, i managed to get it stable enough so that it worked properly in the latest version of Rails. I also got the mail notification working, which i felt was a very important feature of ActiveCollab.</p><p>But there was still a lingering problem: Apart from the OpenID support, RailsCollab didn&#8217;t really offer anything more than ActiveCollab or ProjectPier offered.</p><p>So i thought for a while: What feature could i implement that wasn&#8217;t present in either solutions?</p><p>And then it hit me: an <span class='caps'>API</span>! Though not just any <span class='caps'>API</span>, no. Rather, the <b> <a href='http://www.basecamphq.com/'>BaseCamp</a> API </b>.</p><p>For those of you that don&#8217;t know, BaseCamp was the inspiration behind ActiveCollab (and thus, RailsCollab). From an <span class='caps'>API</span> standpoint, it pretty much has the same features, which was great for me as it mapped quite nicely to the BaseCamp <span class='caps'>API</span>. There were only a few features missing, such as the Message Categories, but those didn&#8217;t take too long to implement.</p><p>So i pretty much ended up with a nice and shiny implementation of the Basecamp <span class='caps'>API</span> (minus two minor functions which i have yet to implement). Which meant that i could use all of those fancy third party Basecamp tools widgets with RailsCollab as well.</p><p>However there was a snag. While RailsCollab worked fine in development mode, it failed to work properly in production mode due to some problem with controller helpers &#8211; which as you can imagine was highly frustrating.</p><p>Ruby on Rails might be a great web development framework for getting things up and running quickly, but when you start having such simple problems that cannot easily be debugged, and to top it all off it&#8217;s inherently slow, then it starts to look more like the web development framework from hell.</p><p>Rants aside, i somewhat hope the lure of the Basecamp <span class='caps'>API</span> implementation will generate more interest in RailsCollab. Though even if it doesn&#8217;t, i will still have the satisfaction of knowing i put some effort into polishing it off and turning it into a real product.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Linux on the desktop? Was i crazy?!</title>

		<link>http://www.cuppadev.co.uk/linux-on-the-desktop-was-i-crazy/</link>
		<comments>http://www.cuppadev.co.uk/linux-on-the-desktop-was-i-crazy/#comments</comments>
		<pubDate>Mon, 29 Oct 2007 00:00:00 GMT</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=124</guid>
		<description><![CDATA[<p>For those of you have read my blog previously, you may have noticed i bumped in a <a href='http://cuppadev.co.uk/2007/9/10/using-macfuse-to-replace-filevault'>few</a> <a href='http://cuppadev.co.uk/2007/8/9/ubuntu-gutsy-gibbon-tribe-4'>linux</a> <a href='http://cuppadev.co.uk/2007/7/28/quicksilver-on-linux'>related</a> <a href='http://cuppadev.co.uk/2007/7/24/the-horror-of-recordmydesktop'>posts</a> here and there. This was mainly due to the fact that i was experimenting with using linux as a desktop operating system (something which i have tried in the past), as i wasn&#8217;t too confident of where Mac <span class='caps'>OS X</span> was going. This ultimately included installing it via <a href='http://www.apple.com/macosx/features/bootcamp.html'>BootCamp</a> on my Macbook.</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/2007/10/29/live-works.jpg'><img alt='Ubuntu desktop' src='http://www.cuppadev.co.uk/assets/2007/10/29/live-works_th.jpg' title='Ubuntu desktop' /></a></p><p>Unfortunately i have now reached the end of my teather with regards to using...]]></description>
		<content:encoded><![CDATA[<p>For those of you have read my blog previously, you may have noticed i bumped in a <a href='http://cuppadev.co.uk/2007/9/10/using-macfuse-to-replace-filevault'>few</a> <a href='http://cuppadev.co.uk/2007/8/9/ubuntu-gutsy-gibbon-tribe-4'>linux</a> <a href='http://cuppadev.co.uk/2007/7/28/quicksilver-on-linux'>related</a> <a href='http://cuppadev.co.uk/2007/7/24/the-horror-of-recordmydesktop'>posts</a> here and there. This was mainly due to the fact that i was experimenting with using linux as a desktop operating system (something which i have tried in the past), as i wasn&#8217;t too confident of where Mac <span class='caps'>OS X</span> was going. This ultimately included installing it via <a href='http://www.apple.com/macosx/features/bootcamp.html'>BootCamp</a> on my Macbook.</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/2007/10/29/live-works.jpg'><img alt='Ubuntu desktop' src='http://www.cuppadev.co.uk/assets/2007/10/29/live-works_th.jpg' title='Ubuntu desktop' /></a></p><p>Unfortunately i have now reached the end of my teather with regards to using Linux as a Desktop operating system. Quite simply i kept bumping into too many issues which required manual workarounds, if there was even a solution at all.</p><p>&lt;!<del>-more</del>-&gt;</p><p>I started off by trying one of the release candidates for the latest release of Ubuntu, version 7.10. This initially impressed me as when i booted off the installation CD, almost everything appeared to work out-of-the-box. However upon installing it on my Macbook, the novelty wore off as i realised that crucial features of the Macbook &#8211; the camera, the IR, even the trackpad either didn&#8217;t work properly, or didn&#8217;t work at all.</p><p>For example:</p><ul>
<li>The default trackpad configuration was abysmal, and i couldn&#8217;t find any configuration tool which gave me the same amount of customizability as the one in Mac <span class='caps'>OS X</span> in order to fix it.</li>
<li>I never got the iSight working &#8211; though then again this wasn&#8217;t much of a problem as Skype for Linux doesn&#8217;t even support video cameras.</li>
<li>Whilst the sound worked, configuring it was a pain in the ass as there were too many confusing options to choose from.</li>
<li>I tried to get the <span class='caps'>DVI</span> out to work. I ended up breaking the X server and spent ages trying to fix it. Safe to say i never got it to work.</li>
<li>OpenGL support on the Macbook was sub-par.</li>
<li>Intergration between applications varied from being good to abysmal.</li>
</ul><p>( <i>It should be stressed that all of these issues persisted through to the stable release of Ubuntu 7.10</i> )</p><p>In fact, you can see a nice list of all the problems you have to fix out of the box <a href='http://help.ubuntu.com/community/MacBook'>here</a>.</p><p>A week or two ago, Ubuntu 7.10 became officially stable, so i decided to try out one of its variants to see if it fared any better on my Macbook. I chose Kubuntu as i had previous experience with using <span class='caps'>KDE</span> from using SuSE Linux and figured it might turn out to be a better desktop experience.</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/2007/10/29/kutunbu-wks.jpg'><img alt='Kubuntu Desktop' src='http://www.cuppadev.co.uk/assets/2007/10/29/kutunbu-wks_th.jpg' title='Kubuntu Desktop' /></a></p><p>On the contrary, Kubuntu was anything but a better desktop experience when compared to Ubuntu. A lot of the killer features present in Ubuntu &#8211; <a href='http://www.compiz-fusion.org/'>Compiz Fusion</a>, simple administration tools, even mappings for the brightness controls were not present in Kubuntu. It was also more difficult to configure as there were simply too many configuration options to choose from, as is illustrated by the comparison of the &#8220;Keyboard Shortcuts&#8221; dialog in Kubuntu (which uses <span class='caps'>KDE</span>) and Ubuntu (which uses Gnome) bellow:</p><p style='text-align:center;'><img alt='Would you like the other menu, sir?' src='http://www.cuppadev.co.uk/assets/2007/10/29/kvg.jpg' title='Would you like the other menu, sir?' /></p><p>I even tried the beta <span class='caps'>KDE4</span> packages, in the hope that maybe <span class='caps'>KDE4</span> had improved on <span class='caps'>KDE3</span>. I was sorely dissapointed, as instead of <a href='http://www.cuppadev.co.uk/assets/2007/10/29/kde4-wisll.jpg'>this</a> i got <a href='http://www.cuppadev.co.uk/assets/2007/10/29/kde4-will.png'>this</a>.</p><p>Safe to say i have come to the conclusion that currently neither Ubuntu or Kubuntu are quite up to scratch when compared to the standards set by Mac <span class='caps'>OS X</span>. In fact if suddenly all copies of Mac <span class='caps'>OS X</span> were obliterated, i&#8217;d probably take a risk and use <a href='http://www.haiku-os.org'>Haiku</a>.</p><p>As for the future, who knows? But as for now, i think i&#8217;ll stick to what i like best &#8211; <a href='http://www.apple.com/macosx/'>Mac <span class='caps'>OS X</span></a>.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Flash Plays SCUMM (sort of)</title>

		<link>http://www.cuppadev.co.uk/flash-plays-scumm-sort-of/</link>
		<comments>http://www.cuppadev.co.uk/flash-plays-scumm-sort-of/#comments</comments>
		<pubDate>Sat, 06 Oct 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=120</guid>
		<description><![CDATA[<p>Soon after bumping into <a href='http://cuppadev.co.uk/2007/10/4/haxe-web-oriented-universal-language'>haXe</a> and <a href='http://blog.brokenfunction.com/2007/07/20/flash-plays-doom/'>Doomed Online</a>, i somehow got the strange idea that i could get flash to play <span class='caps'>SCUMM</span> games, like <a href='http://www.scummvm.org/'>ScummVM</a>.</p><p>Safe to say, i ended up with this rather odd Flash-based app written in haXe which when provided with the &#8221;.000&#8221; and &#8221;.001&#8221; files of any unencrypted <span class='caps'>V6 SCUMM</span> game will be able to load and play it. Or rather, attempt to.</p><p style='text-align:center;'><img alt='Obligatory example image' src='http://cuppadev.co.uk/assets/2007/10/6/hiscumm-ex.png' title='Obligatory example image' /></p><p>Sadly i bumped into a problem in the image decode routines, so what is displayed isn&#8217;t pretty. But it is quite...]]></description>
		<content:encoded><![CDATA[<p>Soon after bumping into <a href='http://cuppadev.co.uk/2007/10/4/haxe-web-oriented-universal-language'>haXe</a> and <a href='http://blog.brokenfunction.com/2007/07/20/flash-plays-doom/'>Doomed Online</a>, i somehow got the strange idea that i could get flash to play <span class='caps'>SCUMM</span> games, like <a href='http://www.scummvm.org/'>ScummVM</a>.</p><p>Safe to say, i ended up with this rather odd Flash-based app written in haXe which when provided with the &#8221;.000&#8221; and &#8221;.001&#8221; files of any unencrypted <span class='caps'>V6 SCUMM</span> game will be able to load and play it. Or rather, attempt to.</p><p style='text-align:center;'><img alt='Obligatory example image' src='http://cuppadev.co.uk/assets/2007/10/6/hiscumm-ex.png' title='Obligatory example image' /></p><p>Sadly i bumped into a problem in the image decode routines, so what is displayed isn&#8217;t pretty. But it is quite capable of executing enough opcode&#8217;s to get to the input event loop in Alban Bedel&#8217;s road example for his scummc compiler, which is great.</p><p>As for other games, i would doubt that they would get very far. A lot still needs to be implemented in the runtime.</p><p>In any case, if you dare you can try out my Flash-based <span class='caps'>SCUMM</span> interpreter by downloading and extracting <a href='http://cuppadev.co.uk/assets/2007/10/6/hiscumm-bin.tar.gz'>this</a> archive. Simply load &#8220;test.html&#8221; into your web browser. Note though that you will need Flash 9 in order to run the interpreter.</p><p>In addition i also decided to open up the code for everyone to look at. It&#8217;s a mess, but it works. You can grab it from <a href='http://cuppadev.co.uk/assets/2007/10/5/hiscumm.tar.gz'>here</a>.</p><p>Finally i would like to congratulate the ScummVM team for their <span class='caps'>SCUMM</span> interpreter and Alban Bedel for his scummc compiler. Without their efforts, i wouldn&#8217;t have had any code or references from which to base my haXe-based <span class='caps'>SCUMM</span> interpreter.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>HaXe - Web oriented universal language!</title>

		<link>http://www.cuppadev.co.uk/haxe-web-oriented-universal-language/</link>
		<comments>http://www.cuppadev.co.uk/haxe-web-oriented-universal-language/#comments</comments>
		<pubDate>Thu, 04 Oct 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=119</guid>
		<description><![CDATA[<p>A while after i bumped into <a href='http://cuppadev.co.uk/2007/9/18/doomed-online'>Doomed Online</a>, i decided to investigate the pipeline for making <a href='http://www.adobe.com/products/flashplayer/'>Flash 9</a> games.</p><p>Compared to a few years ago, it seems like an increasingly lucrative game development platform. Pretty much everything you would need to implement for a game is possible with Flash 9, including such things as <a href='http://blog.papervision3d.org/'>3D Rendering</a>. In a way it&#8217;s comparable to the late-90&#8217;s PC gaming scene. I have no doubt that you could probably make something as sophisticated as, say, Tomb Raider with Flash 9.</p><p>However my big problem with Flash is that it is still a closed...]]></description>
		<content:encoded><![CDATA[<p>A while after i bumped into <a href='http://cuppadev.co.uk/2007/9/18/doomed-online'>Doomed Online</a>, i decided to investigate the pipeline for making <a href='http://www.adobe.com/products/flashplayer/'>Flash 9</a> games.</p><p>Compared to a few years ago, it seems like an increasingly lucrative game development platform. Pretty much everything you would need to implement for a game is possible with Flash 9, including such things as <a href='http://blog.papervision3d.org/'>3D Rendering</a>. In a way it&#8217;s comparable to the late-90&#8217;s PC gaming scene. I have no doubt that you could probably make something as sophisticated as, say, Tomb Raider with Flash 9.</p><p>However my big problem with Flash is that it is still a closed platform. I have yet to find any open source re-implementation of the Flash runtime that fully runs Flash 7 files, let alone Flash 9. And whilst the Flash 9 compiler is supposedly <a href='http://labs.adobe.com/wiki/index.php/Flex:Open_Source'>going to be open source&#8217;d</a> by Adobe, i have yet to see any indication that this is really going to happen.</p><p style='text-align:left;'><img alt='HaXe Logo' src='http://cuppadev.co.uk/assets/2007/10/4/haxe_banner.png' style='border:0px;' title='HaXe Logo' /></p>
<p>Thankfully, i found a solution : <a href='http://www.haxe.org'>HaXe</a>. It is essentially a fully featured programming language that can output to one of three formats: <ul>
<li>Adobe Flash (7, 8, or 9)</li>
<li><a href='http://nekovm.org/'>Neko VM</a> (runs as a standalone app or a web app or perhaps embedded elsewhere)</li>
<li>JavaScript (though sadly doesn&#8217;t have a nice <span class='caps'>RIA</span> toolkit which writes all the <span class='caps'>HTML</span> like, say, <a href='http://openlaszlo.org/'>OpenLaszlo</a>)</li>
</ul></p>
<p>So in essence, with HaXe i can bypass my &#8220;closed platform&#8221; nag point and instead make a version of my game or app that works in Neko or perhaps just in a bog standard Web Browser. In addition i can consolidate my web development into one cool programming language. Great!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Doomed Online</title>

		<link>http://www.cuppadev.co.uk/doomed-online/</link>
		<comments>http://www.cuppadev.co.uk/doomed-online/#comments</comments>
		<pubDate>Tue, 18 Sep 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=118</guid>
		<description><![CDATA[<p>Just as i thought i had found some of the most <a href='http://cuppadev.co.uk/2007/9/15/freaky-flash'>freakiest flash apps</a>, i found this rather playable re-implementation of doom called <a href='http://code.google.com/p/doomedonline/'>Doomed Online</a>.</p><p style='text-align:center;'><img alt='Obligatory Screenshot' src='http://cuppadev.co.uk/assets/2007/9/18/doom-screenshot.png' title='Obligatory Screenshot' /></p><p>What is amazing about it is that it uses the <strong>original data files</strong> &#8211; something which i never considered would have been possible with flash. But then again i&#8217;ve not quite been keeping up with all of the technical advances in flash over the years, so it is really no surprise.</p><p>The demo is available <a href='http://doomedonline.googlecode.com/files/doom.swf'>here</a>. For those of you who might have checked out the <a...]]></description>
		<content:encoded><![CDATA[<p>Just as i thought i had found some of the most <a href='http://cuppadev.co.uk/2007/9/15/freaky-flash'>freakiest flash apps</a>, i found this rather playable re-implementation of doom called <a href='http://code.google.com/p/doomedonline/'>Doomed Online</a>.</p><p style='text-align:center;'><img alt='Obligatory Screenshot' src='http://cuppadev.co.uk/assets/2007/9/18/doom-screenshot.png' title='Obligatory Screenshot' /></p><p>What is amazing about it is that it uses the <strong>original data files</strong> &#8211; something which i never considered would have been possible with flash. But then again i&#8217;ve not quite been keeping up with all of the technical advances in flash over the years, so it is really no surprise.</p><p>The demo is available <a href='http://doomedonline.googlecode.com/files/doom.swf'>here</a>. For those of you who might have checked out the <a href='http://toastytech.com/dooma/index.html'>pre-release versions of Doom</a>, the demo plays very much like them &#8211; as in you can&#8217;t shoot anything and there is no AI. Hopefully in the future these issues will be resolved and it&#8217;ll be that much more interesting to play.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Can you solve this river crossing puzzle?</title>

		<link>http://www.cuppadev.co.uk/can-you-solve-this-river-crossing-puzzle/</link>
		<comments>http://www.cuppadev.co.uk/can-you-solve-this-river-crossing-puzzle/#comments</comments>
		<pubDate>Sat, 08 Sep 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=114</guid>
		<description><![CDATA[<p>After stumbling across the <a href='http://www.mehtanirav.com/'>Entrepreneur Geek</a> blog, i spotted this rather puzzling <a href='http://www.mehtanirav.com/2007/09/08/crossing-the-river/'>river crossing puzzle</a>. Sadly, i haven&#8217;t managed to solve it yet, but i think i&#8217;m close.</p> <strong>Instructions:</strong><ul> <li>Help these people to cross the river, in the next screen.</li> <li>Only two people at a time, at least one adult.</li> <li>Criminal (in striped dress) cannot be left with others, without the Police.</li> <li>Mother cannot be with sons, while father is not around.</li> <li>Father cannot be with daughters, while mother is not around.</li> <li>Click on the <span class='caps'>BIG BLUE BUTTON</span> to start!</li> <li>Click on people to get them on...]]></description>
		<content:encoded><![CDATA[<p>After stumbling across the <a href='http://www.mehtanirav.com/'>Entrepreneur Geek</a> blog, i spotted this rather puzzling <a href='http://www.mehtanirav.com/2007/09/08/crossing-the-river/'>river crossing puzzle</a>. Sadly, i haven&#8217;t managed to solve it yet, but i think i&#8217;m close.</p>
<strong>Instructions:</strong><ul>
	<li>Help these people to cross the river, in the next screen.</li>
	<li>Only two people at a time, at least one adult.</li>
	<li>Criminal (in striped dress) cannot be left with others, without the Police.</li>
	<li>Mother cannot be with sons, while father is not around.</li>
	<li>Father cannot be with daughters, while mother is not around.</li>
	<li>Click on the <span class='caps'>BIG BLUE BUTTON</span> to start!</li>
	<li>Click on people to get them on or off the boat.</li>
	<li>Click on the Red buttons to move the boat to opposite side</li>
</ul><p style='clear:both'><object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0' height='304' width='480'><param name='movie' value='http://www.fungloo.com/arcade/swf/river_crossing.swf' /> <param name='quality' value='high' /><param name='menu' value='true' /><embed height='304' pluginspage='http://www.macromedia.com/go/getflashplayer' quality='high' src='http://www.fungloo.com/arcade/swf/river_crossing.swf' type='application/x-shockwave-flash' width='480' /></object></p>]]></content:encoded>
	</item>
	
	<item>
		<title>ScummC - Make your own SCUMM Adventure Game!</title>

		<link>http://www.cuppadev.co.uk/scummc-make-your-own-scumm-adventure-game/</link>
		<comments>http://www.cuppadev.co.uk/scummc-make-your-own-scumm-adventure-game/#comments</comments>
		<pubDate>Sat, 25 Aug 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=112</guid>
		<description><![CDATA[<p>Back in the good ol&#8217; days of <span class='caps'>DOS</span>, i used to (and still do) like playing adventure games. Specifically, i thought those made by Lucasarts were the best, as they often had simple yet funny plots, and you could pretty much get around them easily. They all had (more or less) consistent interfaces &#8211; from <a href='http://en.wikipedia.org/wiki/Maniac_Mansion'>Maniac Mansion</a> to <a href='http://en.wikipedia.org/wiki/The_Secret_of_Monkey_Island'>The Secret of Money Island</a>, you could tell it was a Lucasart&#8217;s adventure game and that it was going to essentially work the same as the last Lucasart&#8217;s adventure game you played.</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/2007/8/25/maniac_mansion.png'><img alt='Maniac Mansion' src='http://www.cuppadev.co.uk/assets/2007/8/25/maniac_mansion.png' style='width:192px; height:101;'...]]></description>
		<content:encoded><![CDATA[<p>Back in the good ol&#8217; days of <span class='caps'>DOS</span>, i used to (and still do) like playing adventure games. Specifically, i thought those made by Lucasarts were the best, as they often had simple yet funny plots, and you could pretty much get around them easily. They all had (more or less) consistent interfaces &#8211; from <a href='http://en.wikipedia.org/wiki/Maniac_Mansion'>Maniac Mansion</a> to <a href='http://en.wikipedia.org/wiki/The_Secret_of_Monkey_Island'>The Secret of Money Island</a>, you could tell it was a Lucasart&#8217;s adventure game and that it was going to essentially work the same as the last Lucasart&#8217;s adventure game you played.</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/2007/8/25/maniac_mansion.png'><img alt='Maniac Mansion' src='http://www.cuppadev.co.uk/assets/2007/8/25/maniac_mansion.png' style='width:192px; height:101;' title='Maniac Mansion' /></a> <a href='http://www.cuppadev.co.uk/assets/2007/8/25/monkey_island.png'><img alt='The Secret of Monkey Island' src='http://www.cuppadev.co.uk/assets/2007/8/25/monkey_island.png' style='width:192px; height:144;' title='The Secret of Monkey Island' /></a></p><p>&lt;!<del>-more</del>-&gt;
The consistency in part came from the game engine which they all shared in common: <a href='http://en.wikipedia.org/wiki/SCUMM'><span class='caps'>SCUMM</span></a> (Script Creation Utility for Maniac Mansion).  Each game implemented its own set of scripts and resources which could be run in any version of <span class='caps'>SCUMM</span>, provided that they were targeted for the version(s) of <span class='caps'>SCUMM</span> that particular runtime of the engine supported. In a way, it was like the equivalent of Java for adventure games.</p><p>Anyhow, part of the reason i got interested in software development in the first place was that i always wondered how these games were made. I thought it was great how it all fitted together &#8211; the characters, the animation, the scripting, the lot. Eventually i found various projects on the &#8216;net which were aiming to create development system&#8217;s for other adventure game engines (such as those made by Sierra), but nobody seemed interested in <span class='caps'>SCUMM</span>.</p><p>Thankfully in 2004 Alban Bedel made his first release of <a href='http://alban.dotsec.net/7.html'>ScummC</a> &#8211; a tool to compile <span class='caps'>SCUMM</span> scripts (using a C-like language) and assets, and link them together so you could play them in any <span class='caps'>SCUMM</span> runtime that supported version 6 scripts. Although it wasn&#8217;t until late last year that i was confident to download it and try it out. Still, it brought great a great new insight into how these <span class='caps'>SCUMM</span> games were made.</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/2007/8/25/scummc_road.jpg'><img alt='ScummC Example' src='http://www.cuppadev.co.uk/assets/2007/8/25/scummc_road_th.jpg' title='ScummC Example' /></a></p><p>By the time i tried ScummC out, Alban had already made a standalone demo <span class='caps'>SCUMM</span> game which consisted of a single room and a player character. Surprisingly, it was all presented in a top-down view, which wasn&#8217;t quite what i expected from a <span class='caps'>SCUMM</span> adventure. Still, i played around with it and was greatly impressed.</p><p>When i digged down into the demo code though, i was amazed at how much of the interface was powered by script. The action&#8217;s, the inventory, the hover text &#8211; you name it, it was powered by script. Considering almost every Lucasart&#8217;s adventure game i played had that same look and feel, i was really thinking a lot of it was going to be explicitly supported in the engine.</p><p>In any case, soon after i showed interest in the ScummC project, Alban updated his standalone demo with a second room. It was interesting to note that whilst it was incredibly easy to add room&#8217;s to script, it was difficult to create the graphics for the rooms as you had to leave space in the room palette for any actor&#8217;s which might be present in the scene. Nowadays you rarely see modern image editors with support for tailoring palettes in this way, so i was compelled to modify the palcat tool included with ScummC to support pre-appending palettes to images (which for some reason i forget, i needed).</p><p>Another thing which i tasked myself with was how to make a conversation. For this, i had to grab a copy of ScummVM and use the debugger to see which <span class='caps'>SCUMM</span> functions were being called during a typical conversation in Day of the Tentacle. In the end, i concluded that once a conversation is entered, the following things happen:</p><ol>
<li>saveVerbs() is called to hide all the interface elements (normally known as &#8220;verbs&#8221;)</li>
<li>All dialogue items are initialised</li>
<li>setVerbOff() is called on all dialogue items so they don&#8217;t appear</li>
<li>Exit conditions for the dialogue are checked</li>
<li>Each option of dialogue is loaded to a corresponding dialog item (setVerbName()) and turned on (setVerbOn())</li>
<li>The conversation script waits till a dialogue option is selected. If it is, the relevant action corresponding to the dialogue gets executed. If the conversation hasn&#8217;t ended, it loops back to 3. Otherwise it goes on to 7.</li>
<li>All dialogue items are hidden / deleted</li>
<li>restoreVerbs() is called to restore all the interface elements</li>
</ol><p>Which safe to say wasn&#8217;t quite what i expected, which was some specific support in the engine for conversations. Which goes to show that <span class='caps'>SCUMM</span> can be quite flexible.</p><p>Sadly there doesn&#8217;t seem to be a lot of people using ScummC. Though then again, its much more programmer oriented as there is no fancy graphical <span class='caps'>IDE</span> to build games as there is in other adventure game engine&#8217;s such as <a href='http://www.adventuregamestudio.co.uk/'>Adventure Game Studio</a>. Its more of a <span class='caps'>DIY</span> toolset, which doesn&#8217;t quite work well in this age of easy to use graphical interfaces. I can&#8217;t quite see the typical user of one of those interfaces having to blindly type in the following (taken from the ScummC example) in order to define a room and some resources.</p>
<pre><code>#include &amp;lt;scummVars6.s&amp;gt;
#include &quot;common.sch&quot; 

bit welcomed,lost,santaHello,santaPlace,santaReal;
actor santa;
#define SANTA_COLOR 14

// our room
room Road {
// first we define the room parameters
// the background picture
image = &quot;road.bmp&quot;;
// the zplanes
zplane = { &quot;road_mask1.bmp&quot;, &quot;road_mask2.bmp&quot; };

boxd = &quot;road.box&quot;;
trans = 0;

//cycle testCycl = { 60, 0, 103, 111 };
cost santaCost = &quot;santa.cost&quot;;

voice letsgothere = { &quot;letsgothere.voc&quot;, 500 };
voice welcome = { &quot;welcome.voc&quot; };
voice tv = { &quot;file.voc&quot; };

object axe;
...</code></pre>
<p>Still, i think it would be interesting to see where ScummC goes, as there is still a lot to be done with it. I would encourage anyone with some free time and who feels comfortable using lots of commandline tools to check it out.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Number Systems &amp; Bases</title>

		<link>http://www.cuppadev.co.uk/number-systems-bases/</link>
		<comments>http://www.cuppadev.co.uk/number-systems-bases/#comments</comments>
		<pubDate>Thu, 16 Aug 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=110</guid>
		<description><![CDATA[<p>A while back, i writ a program in which one could convert any number from any base to and from base 10. So for example, if i had the number &#8220;10&#8221; in base 3, it would churn out &#8220;3&#8221; in base 10, and vice versa.</p><p>Initially all i got it converting was base 62. However i was not just satisfied with base 62, i wanted it to convert any possible base, defined by any set of symbols. To top it all off, i also made it possible to use unicode symbols via <span class='caps'>UTF</span>-8.</p><p>So for example if i could conjure up...]]></description>
		<content:encoded><![CDATA[<p>A while back, i writ a program in which one could convert any number from any base to and from base 10. So for example, if i had the number &#8220;10&#8221; in base 3, it would churn out &#8220;3&#8221; in base 10, and vice versa.</p><p>Initially all i got it converting was base 62. However i was not just satisfied with base 62, i wanted it to convert any possible base, defined by any set of symbols. To top it all off, i also made it possible to use unicode symbols via <span class='caps'>UTF</span>-8.</p><p>So for example if i could conjure up the following hideous system:</p><table style='border:1px solid black;'>
<tr>
<td><strong>Symbol</strong></td>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td><strong>Value</strong></td>
<td>0</td>
<td>1</td>
<td>2</td>
</tr>
</table><p>...and start saying thing&#8217;s like &#8220;C + C = AB&#8221;.</p><p>For the final touch, i added the ability to specify numbers with numerals. Although i didn&#8217;t quite get the conversion algorithm from base10 to numerals right.</p><p>Safe to say, i ended up with this rather hideous looking app programmed in C. But on the plus side i could:</p><ul>
<li>Feed in a file containing a sequential list of <span class='caps'>UTF</span>-8 formatted symbols to make my own number base system.</li>
<li>Feed in a file containing a list of &#8220;SYMBOL=VALUE&#8221; pair&#8217;s ordered by value to make my own numeral system.</li>
<li>Convert the output of either the previous examples back to base10.</li>
</ul><p>In any case, one can grab the code <a href='http://www.cuppadev.co.uk/assets/2007/8/16/Base.zip'>here</a>. It&#8217;s not pretty, nor is it quite the next killer app &#8211; but i had some fun writing it.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>RailsCollab Demo</title>

		<link>http://www.cuppadev.co.uk/railscollab-demo/</link>
		<comments>http://www.cuppadev.co.uk/railscollab-demo/#comments</comments>
		<pubDate>Sun, 12 Aug 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=109</guid>
		<description><![CDATA[<p>A while back Gary Vaughan suggested i host a demo of <a href='http://railscollab.rubyforge.org'>RailsCollab</a> on my server. Sadly though, i didn&#8217;t have any quick &#38; easy way of adding new demo users to the system, that is until i cooked up <a href='http://www.cuppadev.co.uk/2007/8/11/openid-in-railscollab'>OpenID support</a>.</p><p>Consequently, there is now an OpenID enabled service running on <a href='http://brew.cuppadev.co.uk'>http://brew.cuppadev.co.uk</a>. Provided you have an <a href='http://www.openid.net'>OpenID</a>, you should be able to select the &#8220;Use OpenID&#8221; checkbox and type in your OpenID to login. This will automagically register you with the system, adding you to the &#8220;OpenID&#8221; company and the &#8220;RailsCollab&#8221; project. Afterwards if you want, you...]]></description>
		<content:encoded><![CDATA[<p>A while back Gary Vaughan suggested i host a demo of <a href='http://railscollab.rubyforge.org'>RailsCollab</a> on my server. Sadly though, i didn&#8217;t have any quick &#38; easy way of adding new demo users to the system, that is until  i cooked up <a href='http://www.cuppadev.co.uk/2007/8/11/openid-in-railscollab'>OpenID support</a>.</p><p>Consequently, there is now an OpenID enabled service running on <a href='http://brew.cuppadev.co.uk'>http://brew.cuppadev.co.uk</a>. Provided you have an <a href='http://www.openid.net'>OpenID</a>, you should be able to select the &#8220;Use OpenID&#8221; checkbox and type in your OpenID to login. This will automagically register you with the system, adding you to the &#8220;OpenID&#8221; company and the &#8220;RailsCollab&#8221; project. Afterwards if you want, you can set your password so you can login using a regular username &#38; password, though personally i think typing in your OpenID is a better idea.</p><p>Note that your OpenID provider needs to support handing over identity fields in order for RailsCollab to correctly register you. <a href='http://www.myopenid.com'>MyOpenID</a> is an example of a provider that supports this. Also note that if there is a user with a duplicate username or email in the system, registration will fail.</p><p>I invite anyone to try RailsCollab out.</p><p><strong><span class='caps'>UPDATE</span></strong>: The demo has since been taken down. If you wish to try out RailsCollab, you will need to download and install it yourself.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>OpenID in RailsCollab</title>

		<link>http://www.cuppadev.co.uk/openid-in-railscollab/</link>
		<comments>http://www.cuppadev.co.uk/openid-in-railscollab/#comments</comments>
		<pubDate>Sat, 11 Aug 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=108</guid>
		<description><![CDATA[<p>As mentioned in my <a href='http://www.cuppadev.co.uk/2007/6/22/cloning-activecollab'>Cloning ActiveCollab</a> post, i managed to make a reasonably good clone of <a href='http://activecollab.com/'>ActiveCollab</a> using the <a href='http://www.rubyonrails.org'>Ruby on Rails</a> framework.</p><p>Recently after watching the rather interesting Google TechTalk on <a href='http://video.google.com/videoplay?docid=2288395847791059857&#38;q=openid&#38;total=42&#38;start=0&#38;num=10&#38;so=0&#38;type=search&#38;plindex=0'>The implications of OpenID</a>, i decided to see if i could add <a href='http://openid.net/'>OpenID</a> support to RailsCollab.</p><p style='text-align:left;'><a href='http://www.openid.net'><img alt='OpenID Logo' src='http://www.cuppadev.co.uk/assets/2007/8/11/openid.png' style='border:0px;' title='OpenID Logo' /></a></p><p>OpenID is a pretty nifty decentralised single sign-on system. The process of verifying a user&#8217;s identity is essentially outsourced to an OpenID identity provider, instead of being left to web developer&#8217;s to implement it themselves (and consequently doing a very...]]></description>
		<content:encoded><![CDATA[<p>As mentioned in my <a href='http://www.cuppadev.co.uk/2007/6/22/cloning-activecollab'>Cloning ActiveCollab</a> post, i managed to make a reasonably good clone of <a href='http://activecollab.com/'>ActiveCollab</a> using the <a href='http://www.rubyonrails.org'>Ruby on Rails</a> framework.</p><p>Recently after watching the rather interesting Google TechTalk on <a href='http://video.google.com/videoplay?docid=2288395847791059857&#38;q=openid&#38;total=42&#38;start=0&#38;num=10&#38;so=0&#38;type=search&#38;plindex=0'>The implications of OpenID</a>, i decided to see if i could add <a href='http://openid.net/'>OpenID</a> support to RailsCollab.</p><p style='text-align:left;'><a href='http://www.openid.net'><img alt='OpenID Logo' src='http://www.cuppadev.co.uk/assets/2007/8/11/openid.png' style='border:0px;' title='OpenID Logo' /></a></p><p>OpenID is a pretty nifty decentralised single sign-on system. The process of verifying a user&#8217;s identity is essentially outsourced to an OpenID identity provider, instead of being left to web developer&#8217;s to implement it themselves (and consequently doing a very poor job of it). As a user, i host my identity on any of the numerous OpenID identity providers, preferably one which i can trust. Or if i&#8217;m really paranoid, i can just make my own OpenID identity provider.</p><p>In relation to RailsCollab, it makes sense to have support for OpenID as a key feature is the ability for client&#8217;s to log-on to review progress on a project.</p><p>Without OpenID, you&#8217;d have to give each of your client&#8217;s a username and password, the latter of which you can almost guarantee that someone will forget. And then you need to muck about with setting up an email server so you can send out &#8220;Password reset&#8221; email&#8217;s, unless you want to do it all yourself each time you need to reset it.</p><p>With OpenID, you&#8217;d just have to give each of your client&#8217;s a username and an associated OpenID. There&#8217;s no need to much about with password&#8217;s, as you&#8217;ve outsourced that burden to the OpenID provider. All they need to do to login is type in their OpenID, and their OpenID provider will handle the sign-on process.</p><p style='text-align:center;'><img alt='Obligatory Screenshot' src='http://www.cuppadev.co.uk/assets/2007/8/11/openid_railscollab_login.png' title='Obligatory Screenshot' /></p><p>For anyone crazy enough to actually try RailsCollab with OpenID, you can grab a copy from the Subversion repository on RailsForge. Details are available on the <a href='http://rubyforge.org/projects/railscollab/'>project page</a>.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>OpenLaszlo XML Workaround</title>

		<link>http://www.cuppadev.co.uk/openlaszlo-xml-workaround/</link>
		<comments>http://www.cuppadev.co.uk/openlaszlo-xml-workaround/#comments</comments>
		<pubDate>Thu, 09 Aug 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=105</guid>
		<description><![CDATA[<p>As mentioned in my <a href='http://www.cuppadev.co.uk/2007/8/8/openlaszlo-version-of-the-previous-flex-example'>previous OpenLaszlo post</a>, i had a problem whereby in <span class='caps'>SOLO</span> mode my app would send the <span class='caps'>XML</span> data to the server in urlencode format. This meant that my poor <span class='caps'>REST</span>-based web service barfed up as this was in no way valid <span class='caps'>XML</span>. Safe to say, i wasn&#8217;t best pleased.</p><p>Thankfully though, considering i am interfacing with my own web service, i can change how the server interacts with the request data all i want. So it&#8217;s pretty easy to work around this issue.</p><p>In the case of the <a href='http://www.rubyonrails.org'>Ruby on Rails</a> framework...]]></description>
		<content:encoded><![CDATA[<p>As mentioned in my <a href='http://www.cuppadev.co.uk/2007/8/8/openlaszlo-version-of-the-previous-flex-example'>previous OpenLaszlo post</a>, i had a problem whereby in <span class='caps'>SOLO</span> mode my app would send the <span class='caps'>XML</span> data to the server in urlencode format. This meant that my poor <span class='caps'>REST</span>-based web service barfed up as this was in no way valid <span class='caps'>XML</span>. Safe to say, i wasn&#8217;t best pleased.</p><p>Thankfully though, considering i am interfacing with my own web service, i can change how the server interacts with the request data all i want. So it&#8217;s pretty easy to work around this issue.</p><p>In the case of the <a href='http://www.rubyonrails.org'>Ruby on Rails</a> framework i am using, the easiest way is to make a new mimetype handler which handles our standards hostile custom mimetype (which i promptly called &#8220;application/xml-urlencode&#8221;). Like so:</p>
<pre><code>Mime::Type.register &quot;application/xml-urlencode&quot;, :xml

ActionController::Base.param_parsers[Mime::Type.lookup(
&#39;application/xml-urlencode&#39;)] = Proc.new do
|data|
decoded_data =  CGI::unescape(data) # Decode data
XmlSimple.xml_in(data, {&#39;keeproot&#39; =&amp;gt; true,
&#39;forcearray&#39; =&amp;gt; false}) # Parse decoded XML
end</code></pre>
<p>And then all i have to do in my OpenLaszlo app is something along the lines of:</p>
<pre><code>datasetForSending.setHeader(&quot;Content-Type&quot;, &quot;application/xml-urlencode&quot;);</code></pre>
<p>And hey presto, the data is now recognised!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>OpenLaszlo Version of the Previous Flex Example</title>

		<link>http://www.cuppadev.co.uk/openlaszlo-version-of-the-previous-flex-example/</link>
		<comments>http://www.cuppadev.co.uk/openlaszlo-version-of-the-previous-flex-example/#comments</comments>
		<pubDate>Wed, 08 Aug 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=104</guid>
		<description><![CDATA[<p>As hinted in my <a href='http://www.cuppadev.co.uk/2007/8/6/running-into-flex-limitations'>Running into Flex Limitations</a> post, i finally managed to make a version of the rather nifty <span class='caps'>REST</span>-based project object editor.</p><p>After being told about the magical &#8220;lzpostbody&#8221; parameter by Henry Minsky, i was able to send my <span class='caps'>XML</span> data in the content of my <span class='caps'>POST</span> request (which causes the Rails app to create Project objects).</p><p>Sadly i needed to make a little concession on the &#8220;PUT&#8221; method (which would cause the Rails app to modify the specified object) as i couldn&#8217;t manage to find a way of passing in the &#8220;_method=POST&#8221; parameter in from...]]></description>
		<content:encoded><![CDATA[<p>As hinted in my <a href='http://www.cuppadev.co.uk/2007/8/6/running-into-flex-limitations'>Running into Flex Limitations</a> post, i finally managed to make a version of the rather nifty <span class='caps'>REST</span>-based project object editor.</p><p>After being told about the magical &#8220;lzpostbody&#8221; parameter by Henry Minsky, i was able to send my <span class='caps'>XML</span> data in the content of my <span class='caps'>POST</span> request (which causes the Rails app to create Project objects).</p><p>Sadly i needed to make a little concession on the &#8220;PUT&#8221; method (which would cause the Rails app to modify the specified object) as i couldn&#8217;t manage to find a way of passing in the &#8220;_method=POST&#8221; parameter in from the request as i could with Flex, like so:</p><pre>
<code>
	private function sendProjectUpdate():void
	{
	  var projectUpdate:Object = new Object();

	  projectUpdate['name'] = pname.text;
	  projectUpdate['description'] = description.text;

	  updateProject.url = "http://localhost:3000/projects/" +
	    projs_dg.selectedItem.id + ".xml?_method=PUT";
	  updateProject.send({project:projectUpdate});
	}
</code>
</pre><p>Doing a similar thing in OpenLaszlo didn&#8217;t work (my Rails app doesn&#8217;t seem to pick up the overriding _method). I can only assume that Flex is using some extra hocus pocus behind the scenes to make my app happy enough to go ahead. Maybe i&#8217;ll have to dissect the <span class='caps'>HTTP</span> requests to get to the bottom of it.</p><p>To replace the requirement of &#8220;PUT&#8221;, i just added in another route in my Rails app that goes straight to the update method on the projects controller, like so:</p>
<pre><code>map.connect &#39;test/update/:id&#39;, :controller =&amp;gt; &#39;projects&#39;, :action =&amp;gt; &#39;update&#39;
map.connect &#39;test/update/:id.:format&#39;, :controller =&amp;gt; &#39;projects&#39;, :action =&amp;gt; &#39;update&#39;</code></pre>
<p>In any case, i was happy enough that i could get an equivalent version of my Flex app working in OpenLaszlo. Whilst it doesn&#8217;t have all the glitz and glamour of Flex&#8217;s components, it mostly still works the same, with the exception of the extra &#8220;Refresh&#8221; button which i had to add as i couldn&#8217;t seem to reliably determine when my requests to the server ended, which meant that the projects list doesn&#8217;t always automagically update to reflect the result on the server.</p><p>For reference, the code is located <a href='http://www.cuppadev.co.uk/assets/2007/8/8/manage_test.txt'>here</a>.</p><p><strong><span class='caps'>UPDATE</span></strong>: Whilst this code works fine in the default <span class='caps'>PROXY</span> mode, it seems that in <span class='caps'>SOLO</span> mode the <span class='caps'>XML</span> is escaped (e.g. &#8221;&lt;project&gt;&lt;name&gt;New Project (TEST)!!!!&lt;&#8221;) when sending data, which more or less sucks.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Running into OpenLaszlo Limitations</title>

		<link>http://www.cuppadev.co.uk/running-into-openlaszlo-limitations/</link>
		<comments>http://www.cuppadev.co.uk/running-into-openlaszlo-limitations/#comments</comments>
		<pubDate>Sun, 05 Aug 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=102</guid>
		<description><![CDATA[<p>One of the things that got me interested in <a href='http://www.openlaszlo.org'>OpenLaszlo</a> was its pretty cool databinding features, which meant i could take in data from any standard <span class='caps'>XML</span> document (be it a web page, xmlrpc, or even <span class='caps'>SOAP</span>) and prototype a little interface around it very quickly, as i previously mentioned in my <a href='http://www.cuppadev.co.uk/2007/7/16/another-experiment-with-openlaszlo'>previous</a> <a href='http://www.cuppadev.co.uk/2007/7/11/experiments-with-openlaszlo'>posts</a>.</p><p>However, today i decided to take it a step further. I wanted to provide an interface to edit the data i obtain from a request and send back the results to the server. I also wanted to make use of the <a...]]></description>
		<content:encoded><![CDATA[<p>One of the things that got me interested in <a href='http://www.openlaszlo.org'>OpenLaszlo</a> was its pretty cool databinding features, which meant i could take in data from any standard <span class='caps'>XML</span> document (be it a web page, xmlrpc, or even <span class='caps'>SOAP</span>) and prototype a little interface around it very quickly, as i previously mentioned in my <a href='http://www.cuppadev.co.uk/2007/7/16/another-experiment-with-openlaszlo'>previous</a> <a href='http://www.cuppadev.co.uk/2007/7/11/experiments-with-openlaszlo'>posts</a>.</p><p>However, today i decided to take it a step further. I wanted to provide an interface to edit the data i obtain from a request and send back the results to the server. I also wanted to make use of the <a href='http://www.rubyonrails.org'>Ruby on Rails</a> framework&#8217;s support for <a href='http://en.wikipedia.org/wiki/Representational_State_Transfer'><span class='caps'>REST</span></a>.</p><p>Being the naive person i am, i thought it was going to be a walk in the park. In OpenLaszlo, all you need to do to grab and display your data from the server is:</p><ul>
<li>Make a dataset and point it to your data (e.g. &#8220;http://localhost:3000/projects/1.xml&#8221;)</li>
<li>Make a control with &#8220;datapath&#8221; set to an appropriate location in your dataset in XPath format (e.g. &#8220;dset:/project&#8221;)</li>
<li>Call &#8220;doRequest&#8221; on your dataset</li>
</ul>
<p>The call to &#8220;doRequest&#8221; can be done like so:</p>

<pre><code>dset.setQueryType(&#39;GET&#39;);
dset.doRequest();</code></pre>

<p>So naturally, i thought in order to <span class='caps'>POST</span> the data from the dataset back to the server, i could do: <pre>
<code>
dset.setQueryType('POST');
dset.doRequest();
</code>
</pre></p>
<p>Which of course was <strong>completely wrong</strong>. I assumed that the <span class='caps'>API</span> would work both ways (i.e. sending the data when the querytype is &#8216;POST&#8217;), which of course it didn&#8217;t. The only slightly helpful thing i could do was set the query string. However, this wasn&#8217;t quite compatible with <span class='caps'>REST</span>, so i couldn&#8217;t use it as a solution.</p><p>After searching about a bit though, i came up with another solution:</p>
<pre><code>var dp = new LzDatapointer();
dp.setPointer(parent.datapath);

var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open(&#39;POST&#39;, url, true);
xmlHttpRequest.send(dp.serialize());</code></pre>
<p>&#8220;Great!&#8221; i thought, &#8220;This should work!&#8221;. Sadly though, it didn&#8217;t. It seems that OpenLaszlo&#8217;s XMLHttpRequest doesn&#8217;t send any data in a <span class='caps'>POST</span>. Great.</p><p>A short while later, i realised i should be using a &#8216;PUT&#8217; request for updating my <span class='caps'>REST</span>-ful object. The final nail hit the coffin when i got a nice error message from XHttpRequest &#8211; &#8220;method &#8216;PUT&#8217; not supported, use <span class='caps'>GET</span> or <span class='caps'>POST</span>&#8221;. Aaaagh!!</p><p>Safe to say, OpenLaszlo&#8217;s data binding <span class='caps'>API</span> is pretty one-sided when it comes to data. Grabbing data? fine. Sending data? welcome to hell. And not even XMLHttpRequest is of any use, unless you want to send a long long query string, or just stuff everything in the headers, both options which contradict <span class='caps'>REST</span>.</p><p>In the future i think i&#8217;m going to take a look at Adobe&#8217;s <a href='http://www.adobe.com/products/flex/'>Flex</a>. I suspect it might handle <span class='caps'>REST</span> requests a bit better.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Testing a little Haiku</title>

		<link>http://www.cuppadev.co.uk/testing-a-little-haiku/</link>
		<comments>http://www.cuppadev.co.uk/testing-a-little-haiku/#comments</comments>
		<pubDate>Mon, 23 Jul 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=99</guid>
		<description><![CDATA[<p>For a while now, i have been following the progress of the open source <a href='http://haiku-os.org/'>Haiku</a> project, which aims to re-create <a href='http://en.wikipedia.org/wiki/BeOS'>BeOS 5</a>. BeOs, for those of you that might not know, was a rather cool operating system developed during the late 90&#8217;s.</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/2007/7/23/Beos5_pe.png'><img alt='BeOS R5 Personal Edition, screenshot courtesy of WikiPedia' src='http://www.cuppadev.co.uk/assets/2007/7/23/Beos5_pe_th.jpg' title='BeOS R5 Personal Edition, screenshot courtesy of WikiPedia' /></a> <a href='http://www.cuppadev.co.uk/assets/2007/7/23/haiku_os_1_real.png'><img alt='Haiku' src='http://www.cuppadev.co.uk/assets/2007/7/23/haiku_os_th.jpg' title='Haiku' /></a></p> <p>What amazed me about BeOS is that unlike many operating systems around at the time (and arguably, those around today) it: <ul><li>Booted up and shut down in mere seconds (no...]]></description>
		<content:encoded><![CDATA[<p>For a while now, i have been following the progress of the open source <a href='http://haiku-os.org/'>Haiku</a> project, which aims to re-create <a href='http://en.wikipedia.org/wiki/BeOS'>BeOS 5</a>. BeOs, for those of you that might not know, was a rather cool operating system developed during the late 90&#8217;s.</p><p style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/2007/7/23/Beos5_pe.png'><img alt='BeOS R5 Personal Edition, screenshot courtesy of WikiPedia' src='http://www.cuppadev.co.uk/assets/2007/7/23/Beos5_pe_th.jpg' title='BeOS R5 Personal Edition, screenshot courtesy of WikiPedia' /></a> <a href='http://www.cuppadev.co.uk/assets/2007/7/23/haiku_os_1_real.png'><img alt='Haiku' src='http://www.cuppadev.co.uk/assets/2007/7/23/haiku_os_th.jpg' title='Haiku' /></a></p>
<p>What amazed me about BeOS is that unlike many operating systems around at the time (and arguably, those around today) it: <ul><li>Booted up and shut down in mere seconds (no suspend or hibernate trickery needed)</li>
<li>Wasn&#8217;t bloated to hell (sadly a trend nowadays)</li>
<li>Did multi-tasking right (e.g. didn&#8217;t start choking when one little app decided to do something a bit intensive)</li>
<li>Supported live file searches (before the advent of spotlight &#38; co)</li></ul></p>

<p>Although of course, it wasn&#8217;t all perfect. It did lack a few things, like: <ul><li>Multiple user support (nowadays the norm)</li>
<li>Good hardware support (e.g. for stuff like 3d cards and network adapters)</li>
<li>Great third party support (apart from what you can find on <a href='http://bebits.com/'>BeBits</a>)</li></ul></p>
<p>Regardless, in 2002 Be Inc ceased operations and thus BeOS was more or less dead. That was until the controversial <a href='http://www.zeta-os.com'>Zeta</a> developed by Magnussoft came along. Controversial as it was often claimed that Zeta was developed without the permission of whoever owned the rights to the source code of Be OS. Safe to say, the <a href='http://www.zeta-os.com/cms/news.php?extend.50'>nail hit the coffin</a> earlier this year.</p>
<p>Luckily, Haiku is actually coming along quite nicely nowadays. After trying out the <a href='http://haikuhost.com/housestrain/'>latest test image</a> in qemu, i found it to be almost usable, with the exception of: <ul><li>The networking which i couldn&#8217;t seem to get working properly (although the <span class='caps'>DNS</span> did work, so its probably a qemu issue)</li>
<li>The system started to hang a bit when running one of the demo apps (although on the plus side i could still move the windows around freely)</li>
<li>The sound, which i guess doesn&#8217;t work due to lack of appropriate drivers.</li></ul></p>
<p>Still, considering it was running in qemu with no kernel acceleration module, i thought it was quite responsive. In the future, i hope that the Haiku team will improve stability and hardware support so that developers will seriously consider targeting the Haiku / BeOS platform. Hell, maybe even i&#8217;ll try using it more.</p><p>Ultimately, i hope that software developers in general stop following the trend of more bloat, slower functionality. Can&#8217;t we all just follow examples such as Haiku&#8217;s and make something that is simpler and faster without all of the bloat?</p>]]></content:encoded>
	</item>
	
	<item>
		<title>SSH Tunnel Manager</title>

		<link>http://www.cuppadev.co.uk/ssh-tunnel-manager/</link>
		<comments>http://www.cuppadev.co.uk/ssh-tunnel-manager/#comments</comments>
		<pubDate>Wed, 18 Jul 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=98</guid>
		<description><![CDATA[<p>After reading Gary Vaughan&#8217;s recent blog post on <a href='http://blog.azazil.net/339-macbook-installation-applications-101.html'>MacBook Installation Applications 101</a>, i decided to check out one of the tools he mentioned called <a href='http://projects.tynsoe.org/en/stm/download.php'><span class='caps'>SSH</span> Tunnel Manager</a>.</p><p><img alt='SSH Tunnel Manager' src='http://www.cuppadev.co.uk/assets/2007/7/18/stm.png' style='border:0px;' title='SSH Tunnel Manager' /></p><p><span class='caps'>SSH</span> Tunnel manager is a rather nifty tool which allows you to manage a list of <span class='caps'>SSH</span> tunnels, which basically securely forwards ports on your own machine to a remote one.</p><p>So for example, if i had an administration control panel running on my web server, i might want to make it so that i could only connect to it locally...]]></description>
		<content:encoded><![CDATA[<p>After reading Gary Vaughan&#8217;s recent blog post on <a href='http://blog.azazil.net/339-macbook-installation-applications-101.html'>MacBook Installation Applications 101</a>, i decided to check out one of the tools he mentioned called <a href='http://projects.tynsoe.org/en/stm/download.php'><span class='caps'>SSH</span> Tunnel Manager</a>.</p><p><img alt='SSH Tunnel Manager' src='http://www.cuppadev.co.uk/assets/2007/7/18/stm.png' style='border:0px;' title='SSH Tunnel Manager' /></p><p><span class='caps'>SSH</span> Tunnel manager is a rather nifty tool which allows you to manage a list of <span class='caps'>SSH</span> tunnels, which basically securely forwards ports on your own machine to a remote one.</p><p>So for example, if i had an administration control panel running on my web server, i might want to make it so that i could only connect to it locally (so there would be practically no chance of anyone on the internet accessing it).
But i would still want to access it remotely, and the only way for me to do that is make an <span class='caps'>SSH</span> tunnel which acts as if i am connecting locally on the machine, when in reality i am not.</p><p>Any would-be hacker would need to figure out the login details on my <span class='caps'>SSH</span> server in order to have a chance of accessing the control panel.</p><p>Now whilst this app was great, i noticed something a bit disturbing about it. It turns out that its been quite a while since it was last maintained, and thus it it still a <strong><span class='caps'>PPC</span></strong> binary, meaning if i run it on my brand new shiny <strong>Intel</strong> mac, i have to let Rosetta run, which is memory hungry and gobbles up precious <span class='caps'>CPU</span> time!</p><p>Luckily, the developer also provided the <strong>source code</strong> to the application. So the solution was obvious: i needed to <strong>recompile</strong> this application as a <a href='http://www.apple.com/universal/'>Universal Binary</a>, which means it will run <strong>natively</strong> on both <span class='caps'>PPC</span> and Intel mac&#8217;s.</p>
<p>This didn&#8217;t end up being very hard, i.e.: <ul><li>Download and unpack the source code</li>
<li>Open the project file in XCode (converting it to the new format)</li>
<li>Replace the ssh executable in the resources with the version from /usr/bin</li>
<li>Set the configuration to &#8220;Deployment&#8221; and build</li>
<li>Run it and hope it works</li></ul></p>
<p>Thankfully for me, it built properly (with the exception of a few warnings, though they didn&#8217;t look too serious). So now i have a nice and shiny <strong>native</strong> version of the <span class='caps'>SSH</span> Tunnel Manager on my mac.</p><p>In case anyone doesn&#8217;t want to go through the 5 step solution, or perhaps you don&#8217;t have XCode installed on your machine, <a href='http://www.cuppadev.co.uk/assets/2007/7/18/SSH_Tunnel_Manager.zip'>here is a copy</a> for you to download.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Experiments with OpenLaszlo</title>

		<link>http://www.cuppadev.co.uk/experiments-with-openlaszlo/</link>
		<comments>http://www.cuppadev.co.uk/experiments-with-openlaszlo/#comments</comments>
		<pubDate>Wed, 11 Jul 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=94</guid>
		<description><![CDATA[<p>Recently i decided to try out <a href='http://www.openlaszlo.org/'>OpenLaszlo</a>, the <span class='caps'>RIA</span> platform from <a href='http://www.laszlosystems.com/'>Laszlo Systems</a>. Previously i have tried, but failed to get to grips with it. But the <a href='http://weblog.openlaszlo.org/archives/2007/07/our-first-iphone-app/'>iPhone demonstration</a> on the OpenLaszlo blog spurred my interest again.</p><p><img alt='OpenLaszlo Logo' src='http://www.cuppadev.co.uk/assets/2007/7/11/ol_logo_small.gif' style='border:0px;' title='OpenLaszlo Logo' /></p><p>OpenLaszlo is a bit like <a href='http://www.adobe.com/products/flex/'>Adobe&#8217;s Flex</a>, except that instead of just Flash you can output content for multiple runtimes, such as <span class='caps'>DHTML</span> or <span class='caps'>J2ME</span>. This is very interesting as it opens the doors for creating functional web-based applications which can be run on a multitude of devices.</p><p style='text-align:center;'><a href='http://www.openlaszlo.org/lps4/demos/lzpix/app.lzx?lzr=swf7&#38;lzt=html'><img...]]></description>
		<content:encoded><![CDATA[<p>Recently i decided to try out <a href='http://www.openlaszlo.org/'>OpenLaszlo</a>, the <span class='caps'>RIA</span> platform from <a href='http://www.laszlosystems.com/'>Laszlo Systems</a>. Previously i have tried, but failed to get to grips with it. But the <a href='http://weblog.openlaszlo.org/archives/2007/07/our-first-iphone-app/'>iPhone demonstration</a> on the OpenLaszlo blog spurred my interest again.</p><p><img alt='OpenLaszlo Logo' src='http://www.cuppadev.co.uk/assets/2007/7/11/ol_logo_small.gif' style='border:0px;' title='OpenLaszlo Logo' /></p><p>OpenLaszlo is a bit like <a href='http://www.adobe.com/products/flex/'>Adobe&#8217;s Flex</a>, except that instead of just Flash you can output content for multiple runtimes, such as <span class='caps'>DHTML</span> or <span class='caps'>J2ME</span>. This is very interesting as it opens the doors for creating functional web-based applications which can be run on a multitude of devices.</p><p style='text-align:center;'><a href='http://www.openlaszlo.org/lps4/demos/lzpix/app.lzx?lzr=swf7&#38;lzt=html'><img alt='LZPix, an example OpenLaszlo application' src='http://www.cuppadev.co.uk/assets/2007/7/11/lzpix.jpg' title='LZPix, an example OpenLaszlo application' /></a></p><p>In a way, OpenLaszlo is the perfect solution for creating self-contained Flash or <span class='caps'>DHTML</span> internet widgets, as a lot of the framework emphasizes the use of <span class='caps'>AJAX</span> style requests to dynamically update information on the page rather than taking the aging &#8220;dumb terminal&#8221; approach where you reload the whole page.</p><p>Enough of the theory, i decided to try and make myself a little self-contained OpenLaszlo application. Its task was to get the latest updates off of <a href='http://www.twitter.com'>Twitter</a>, a popular web-based chat system.</p><h2>Starting off</h2><p>OpenLaszlo comes with a nicely designed presentation server which run&#8217;s off <a href='http://tomcat.apache.org/'>Tomcat</a>. On this presentation server, you can develop and even deploy your applications. It is supposed to act as an intermediary between your application and any data it requests, which comes in handy in the case of Flash as it transcodes data such as images into a native format Flash can easily understand.</p><p><img alt='DataFlow for the example weather application' src='http://www.cuppadev.co.uk/assets/2007/7/11/weather_dataflow.png' title='DataFlow for the example weather application' /></p><p>Thankfully, if you don&#8217;t fancy running a bloated Java application server just to deploy your OpenLaszlo application, you can choose to deploy it &#8220;SOLO&#8221; which means it run&#8217;s self-contained. Although of course you loose all the neat caching and transcoding that the presentation server can provide. But looking at the bigger picture, its not that much of a loss.</p><p>Being one who didn&#8217;t want to do things the easy way, i developed much of my Twitter application in the demonstration explorer (not the best environment it has to be said, although later on when i got to the deployment stage i moved the &#8220;lzx&#8221; code onto the actual presentation server).</p><h2>Data binding &#38; Replication</h2><p>The first thing i did was to determine how i could get the recent updates feed from Twitter loaded into OpenLaszlo. Thankfully, OpenLaszlo provides a pretty powerful data binding system. You can take in <span class='caps'>XML</span> from any source and create a rather feature full front end in minutes &#8211; provided of course you have read the documentation and know how to get from A to B.</p><p>Quite simply, in order to just view the data from Twitter, all i had to do was the following:</p><pre>
<code>
&lt;canvas&gt;
&lt;dataset name="dset" request="true" 
type="http" src="http://twitter.com/statuses/public_timeline.xml"/&gt;

&lt;simplelayout axis="y"/&gt;

&lt;!-- Data replication --&gt;
&lt;view datapath="dset:/statuses/status"&gt;
&lt;simplelayout axis="x"/&gt;
&lt;image datapath="user/profile_image_url/text()"/&gt;
&lt;text datapath="user/name/text()"/&gt;
&lt;text&gt; - &lt;/text&gt;
&lt;text datapath="text/text()"/&gt;
&lt;/view&gt;

&lt;/canvas&gt;
</code>
</pre><p>As you can see, i have a &#8220;dataset&#8221; which points to the xml feed for the recent activity on Twitter. This is referenced via the datapath in the view. There are also a few elements in the view which also reference <span class='caps'>XML</span> elements in the dataset, relative to the datapath of the view.</p><p>Whenever the dataset is loaded, OpenLaszlo automatically replicates the view to show every &#8220;status&#8221; element in the dataset. It should also be noted that OpenLaszlo also has the common sense to delete the replicated view&#8217;s whenever you decide to reload the dataset (via calling &#8220;dset.doRequest();&#8221;).</p><p>You might also notice the &#8220;simplelayout&#8221; object which i have placed in both the root &#8220;canvas&#8221; and the replicated view. The purpose of this object is to automatically position elements in the element it is located &#8211; which is nice as it is one less thing for me to think about!</p><h2>Polishing everything up</h2><p>Now i could see the data from Twitter, i needed to polish everything up. Importantly, i needed a button to invoke the request on the dataset, and i needed a scrollbar to scroll the list of statuses which were replicated.</p><p style='text-align:center;'><img alt='Twitter application header' src='http://www.cuppadev.co.uk/assets/2007/7/11/twt_ol_header.png' title='Twitter application header' /></p><p>The button was easy. I decided to add a header at the top which contains the button and also some text which tells the user if something is happening. As for the loading text, it uses OpenLaszlo&#8217;s useful constraints feature so it always appears in the right place relative to the width of the page (in this case, right aligned).</p><p style='text-align:center;'><img alt='Twitter application scrollbar' src='http://www.cuppadev.co.uk/assets/2007/7/11/twt_ol_scroll.jpg' title='Twitter application scrollbar' /></p><p>The scrollbar was the hard part. I ended up having to nest the replicated views in another view in order to get the scrollbar to appear correctly (as otherwise the simplelayout would position the scrollbar below the list of statuses). I also had to play about with the width&#8217;s of the views and turn on the clipping so that when everything scrolled, the text didn&#8217;t draw over everything else.</p><h2>The end result</h2><p>After much frustration, here is the end result!</p><p style='text-align: center;'><object height='250' width='500'><param name='movie' value='http://www.cuppadev.co.uk/assets/2007/7/11/twitter.lzx.swf' /><param name='wmode' value='transparent' /><embed height='250' src='http://www.cuppadev.co.uk/assets/2007/7/11/twitter.lzx.swf' type='application/x-shockwave-flash' width='500' wmode='transparent' /></object></p><p>I also decided to add in a little fade-in animation when the images load, which makes everything look that bit cooler.</p><p>For reference, here is the code i ended up with. Feel free to copy and experiment with it!</p><pre>
<code>
&lt;canvas&gt;
&lt;dataset name="dset" 
ondata="header.throbber.setText('');" 
type="http" src="http://twitter.com/statuses/public_timeline.xml"&gt;
&lt;/dataset&gt;

&lt;simplelayout axis="y"/&gt;

&lt;!-- Header --&gt;

&lt;view name="header" width="${parent.width}" bgcolor="#CCCCCC"&gt;
&lt;button&gt;Update
&lt;handler name="onclick"&gt;
parent.throbber.setText("Updating...");
dset.doRequest();
&lt;/handler&gt;
&lt;/button&gt;

&lt;text name="throbber" x="${parent.width - this.width}"&gt;
&lt;/text&gt;
&lt;/view&gt;

&lt;!-- Scrollbar container --&gt;

&lt;view width="${parent.width}" 
height="${parent.height-header.height}" clip="true"&gt;
&lt;scrollbar name="scroller" axis="y"/&gt;

&lt;view width="${parent.width-parent.scroller.width}" clip="true"&gt;

&lt;!-- Data replication --&gt;

&lt;simplelayout axis="y"/&gt;

&lt;view datapath="dset:/statuses/status" visible="false"&gt;
&lt;simplelayout axis="x"/&gt;
&lt;image datapath="user/profile_image_url/text()"&gt;
&lt;method event="onload"&gt;
parent.setOpacity(0);
parent.setVisible(true);
parent.animate("opacity", 1, 1000, false);
&lt;/method&gt;
&lt;/image&gt;
&lt;text datapath="user/name/text()" fontstyle="bold"/&gt;
&lt;text&gt; - &lt;/text&gt;
&lt;text datapath="text/text()" fgcolor="#AAAAAA"/&gt;
&lt;/view&gt;
&lt;/view&gt;

&lt;/view&gt;

&lt;/canvas&gt;
</code>
</pre>]]></content:encoded>
	</item>
	
	<item>
		<title>The Web on a PocketPC</title>

		<link>http://www.cuppadev.co.uk/the-web-on-a-pocketpc/</link>
		<comments>http://www.cuppadev.co.uk/the-web-on-a-pocketpc/#comments</comments>
		<pubDate>Tue, 10 Jul 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=93</guid>
		<description><![CDATA[<p>Unless you have been hiding in the dark these past few weeks, you&#8217;ll have heard about Apple&#8217;s new product, the iPhone. The which i think is most most striking about this new mobile phone is not the cool multi touch interface, or the springy interface, or even its minimalistic look. Rather, it has a web browser that actually works properly!</p><p style='text-align:center;'><img alt='Apple&apos;s iPhone' src='http://www.cuppadev.co.uk/assets/2007/7/10/iphone.jpg' title='Apple&apos;s iPhone' /></p><p>Sadly, whilst Apple may have seen the light and put the time and effort into making a good web browsing experience, the same cannot be said for a lot of other mobile device manufacturers.</p><p>Just...]]></description>
		<content:encoded><![CDATA[<p>Unless you have been hiding in the dark these past few weeks, you&#8217;ll have heard about Apple&#8217;s new product, the iPhone. The which i think is most most striking about this new mobile phone is not the cool multi touch interface, or the springy interface, or even its minimalistic look. Rather, it has a web browser that actually works properly!</p><p style='text-align:center;'><img alt='Apple&apos;s iPhone' src='http://www.cuppadev.co.uk/assets/2007/7/10/iphone.jpg' title='Apple&apos;s iPhone' /></p><p>Sadly, whilst Apple may have seen the light and put the time and effort into making a good web browsing experience, the same cannot be said for a lot of other mobile device manufacturers.</p><p>Just to show you how bad things can get, i decided to try out a few web browsers on my PocketPC device, a <a href='http://www.dell.com'>Dell</a> Axim <span class='caps'>X50V</span>. For those of you who don&#8217;t know, it is one of Dell&#8217;s last PocketPC devices which uses Microsoft&#8217;s &#8220;Windows Mobile&#8221; (otherwise known as Windows CE). It has also got a nice <span class='caps'>VGA</span> screen, giving 640&#215;480 pixels of real screen estate.</p><p style='text-align:center;'><img alt='Dell Axim X50v' src='http://www.cuppadev.co.uk/assets/2007/7/10/axim_x50v.jpg' title='Dell Axim X50v' /></p>
<p>The browsers i decided to try out are as follows: <ul><li><a href='http://en.wikipedia.org/wiki/Pocket_Internet_Explorer'>Pocket Internet Explorer</a></li><li><a href='http://www.opera.com/products/mobile'>Opera Mobile</a></li><li><a href='http://www.mozilla.org/projects/minimo/'>MiniMo</a></li></ul></p>

<p>In each instance, i tried 3 of my favorite websites, i.e.: <ul><li><a href='http://www.youtube.com'>YouTube</a></li><li><a href='http://news.bbc.co.uk/'><span class='caps'>BBC</span> News</a></li><li><a href='http://www.techcrunch.com/'>TechCrunch</a></li></ul></p>
<p>In addition, to make things a bit more interesting i only used the default portrait mode on my device, meaning the resolution was really 480&#215;640 pixels.</p><h2>Pocket Internet Explorer</h2><p><i>For reference, i used the version bundled with Windows Mobile 5.</i></p><p class='center' style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/2007/7/10/youtube_desktop_pie.jpg'><img alt='Youtube Desktop PIE' src='http://www.cuppadev.co.uk/assets/2007/7/10/youtube_desktop_pie_th.jpg' title='Youtube Desktop PIE' /></a><a href='http://www.cuppadev.co.uk/assets/2007/7/10/youtube_default_pie.jpg'><img alt='Youtube Default PIE' src='http://www.cuppadev.co.uk/assets/2007/7/10/youtube_default_pie_th.jpg' title='Youtube Default PIE' /></a><a href='http://www.cuppadev.co.uk/assets/2007/7/10/youtube_onecolumn_pie.jpg'><img alt='Youtube One column PIE' src='http://www.cuppadev.co.uk/assets/2007/7/10/youtube_onecolumn_pie_th.jpg' title='Youtube One column PIE' /></a></p><p class='center' style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/2007/7/10/bbc_desktop_pie.jpg'><img alt='BBC News Desktop PIE' src='http://www.cuppadev.co.uk/assets/2007/7/10/bbc_desktop_pie_th.jpg' title='BBC News Desktop PIE' /></a><a href='http://www.cuppadev.co.uk/assets/2007/7/10/bbc_default_pie.jpg'><img alt='BBC News Default PIE' src='http://www.cuppadev.co.uk/assets/2007/7/10/bbc_default_pie_th.jpg' title='BBC News Default PIE' /></a><a href='http://www.cuppadev.co.uk/assets/2007/7/10/bbc_onecolumn_pie.jpg'><img alt='BBC News One column PIE' src='http://www.cuppadev.co.uk/assets/2007/7/10/bbc_onecolumn_pie_th.jpg' title='BBC News One column PIE' /></a></p><p class='center' style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/2007/7/10/techcrunch_desktop_pie.jpg'><img alt='Techcrunch Desktop PIE' src='http://www.cuppadev.co.uk/assets/2007/7/10/techcrunch_desktop_pie_th.jpg' title='Techcrunch Desktop PIE' /></a><a href='http://www.cuppadev.co.uk/assets/2007/7/10/techcrunch_default_pie.jpg'><img alt='Techcrunch Default PIE' src='http://www.cuppadev.co.uk/assets/2007/7/10/techcrunch_default_pie_th.jpg' title='Techcrunch Default PIE' /></a><a href='http://www.cuppadev.co.uk/assets/2007/7/10/techcrunch_onecolumn_pie.jpg'><img alt='Techcrunch One column PIE' src='http://www.cuppadev.co.uk/assets/2007/7/10/techcrunch_onecolumn_pie_th.jpg' title='Techcrunch One column PIE' /></a></p><p>This browser comes bundled with Windows Mobile. Like its desktop counterpart, it struggles to correctly render a lot of the pages i visited. It also didn&#8217;t help when all the images and whatnot were drawn twice the size.</p><p>Although on the plus side, it felt much more responsive than the other browsers i tried!</p><p>There were a total of three display modes available, i.e.:</p><ul><li>Desktop</li><li>Default</li><li>One column</li></ul><p>Another interesting feature of Pocket Internet Explorer is that if you <a href='http://www.adobe.com/products/flashplayer_pocketpc/downloads/player.html'>download a plugin</a> from Adobe, you can enable support for Flash movies in the browser. Unfortunately it only supports up to version 7, and even then you will be lucky if you can get it to work properly on your typical run-of-the-mill Flash game.</p><p>One major show stopper issue i did find with Pocket Internet explorer is that the JavaScript support appeared to be substandard at best. For example when i tried YouTube, instead of the videos all i got was a JavaScript related error message.</p><h2>Opera Mobile</h2><p><i>For reference, i used the 8.65 beta.</i></p><p class='center' style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/2007/7/10/youtube_desktop_opera.jpg'><img alt='Youtube Desktop Opera' src='http://www.cuppadev.co.uk/assets/2007/7/10/youtube_desktop_opera_th.jpg' title='Youtube Desktop Opera' /></a><a href='http://www.cuppadev.co.uk/assets/2007/7/10/youtube_fitscreen_opera.jpg'><img alt='Youtube Fit to screen Opera' src='http://www.cuppadev.co.uk/assets/2007/7/10/youtube_fitscreen_opera_th.jpg' title='Youtube Fit to screen Opera' /></a><a href='http://www.cuppadev.co.uk/assets/2007/7/10/youtube_single_opera.jpg'><img alt='Youtube Single Opera' src='http://www.cuppadev.co.uk/assets/2007/7/10/youtube_single_opera_th.jpg' title='Youtube Single Opera' /></a></p><p class='center' style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/2007/7/10/bbc_desktop_opera.jpg'><img alt='BBC News Desktop Opera' src='http://www.cuppadev.co.uk/assets/2007/7/10/bbc_desktop_opera_th.jpg' title='BBC News Desktop Opera' /></a><a href='http://www.cuppadev.co.uk/assets/2007/7/10/bbc_fitscreen_opera.jpg'><img alt='BBC News Fit to screen Opera' src='http://www.cuppadev.co.uk/assets/2007/7/10/bbc_fitscreen_opera_th.jpg' title='BBC News Fit to screen Opera' /></a><a href='http://www.cuppadev.co.uk/assets/2007/7/10/bbc_single_opera.jpg'><img alt='BBC News Single Opera' src='http://www.cuppadev.co.uk/assets/2007/7/10/bbc_single_opera_th.jpg' title='BBC News Single Opera' /></a></p><p class='center' style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/2007/7/10/techcrunch_desktop_opera.jpg'><img alt='Techcrunch Desktop Opera' src='http://www.cuppadev.co.uk/assets/2007/7/10/techcrunch_desktop_opera_th.jpg' title='Techcrunch Desktop Opera' /></a><a href='http://www.cuppadev.co.uk/assets/2007/7/10/techcrunch_fitscreen_opera.jpg'><img alt='Techcrunch Fit to screen Opera' src='http://www.cuppadev.co.uk/assets/2007/7/10/techcrunch_fitscreen_opera_th.jpg' title='Techcrunch Fit to screen Opera' /></a><a href='http://www.cuppadev.co.uk/assets/2007/7/10/techcrunch_single_opera.jpg'><img alt='Techcrunch Single Opera' src='http://www.cuppadev.co.uk/assets/2007/7/10/techcrunch_single_opera_th.jpg' title='Techcrunch Single Opera' /></a></p><p>I first tried Opera Mobile last year when they released a public beta. In all, i didn&#8217;t have any major issues with responsiveness. It also rendered a lot of the pages i visited correctly, and even had a &#8220;Fit to Screen&#8221; option where i could view the page scaled down width-wise so it fitted onto my screen &#8211; great!</p><p>Sadly this was the only browser that made a good attempt at displaying each web site correctly, although in Portrait mode everything tends to get a bit squished up.</p>
<p>With regard to display modes, there were three: <ul><li>Desktop</li><li>Fit to screen</li><li>Single</li></ul></p>
<p>Like Pocket Internet Explorer, it can utilize the Adobe Flash plugin for view Flash 7 content. Combined with the superior JavaScript support, you can actually use YouTube. However, the video&#8217;s slow <i>everything</i> down <em>a lot</em>, for instance you can tell in the &#8220;fit to screen&#8221; desktop that it spent so much time playing the embedded flash video&#8217;s that it didn&#8217;t want to load the images.</p><p>Unlike Pocket Internet Explorer, it supported tabbed browsing, which pretty much made sense on a PocketPC.</p><h2>MiniMo</h2><p><i>For reference, i used the 0.2 beta.</i></p><p class='center' style='text-align:center;'><a href='http://www.cuppadev.co.uk/assets/2007/7/10/youtube_minimo.jpg'><img alt='Youtube Minimo' src='http://www.cuppadev.co.uk/assets/2007/7/10/youtube_minimo_th.jpg' title='Youtube Minimo' /></a><a href='http://www.cuppadev.co.uk/assets/2007/7/10/bbc_minimo.jpg'><img alt='BBC News Minimo' src='http://www.cuppadev.co.uk/assets/2007/7/10/bbc_minimo_th.jpg' title='BBC News Minimo' /></a><a href='http://www.cuppadev.co.uk/assets/2007/7/10/techcrunch_minimo.jpg'><img alt='Techcrunch Minimo' src='http://www.cuppadev.co.uk/assets/2007/7/10/techcrunch_minimo_th.jpg' title='Techcrunch Minimo' /></a></p><p>Essentially, this is Firefox for your Pocket PC. Which considering the hardware constraints, does not bode well. To put a long story short, this seemed the least responsive of the browsers i tried. I also encountered a lot of bugs, such as when i tried typing into text fields using the on-screen keyboard, i sometimes could not get rid of it. There was also the occasional crash, right when i least expected it.</p><p>Oddly enough i could not find any way of explicitly changing the display mode, so i was stuck with the default.</p><p>Like Opera Mobile, Minimo supported tabbed browsing. Although i couldn&#8217;t help thinking that the size of the tabs was a bit on the small side (compared to Opera Mobile).</p><p>Unlike Pocket Internet Explorer and Opera Mobile, Minimo could not make use of the Adobe Flash plugin. Considering the relative disappointment with compatibility with Flash content though, its not much of a loss. Still, it would have been nice.</p><h2>To conclude</h2><p>In general, browsing the web on a PocketPC device is a major disappointment. The only browser which stood out was Opera Mobile, which is great if you are willing to shelve out the money to pay for it. Arguably though, a decent web browser should have already been included in Windows Mobile.</p><p>Perhaps in the future web browsers on your typical <span class='caps'>PDA</span>&#8217;s and Mobile Smartphone&#8217;s will get better. Until then, one can only hope.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Cloning ActiveCollab</title>

		<link>http://www.cuppadev.co.uk/cloning-activecollab/</link>
		<comments>http://www.cuppadev.co.uk/cloning-activecollab/#comments</comments>
		<pubDate>Fri, 22 Jun 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=85</guid>
		<description><![CDATA[<p>Just over 3 months ago, the developer of a a nifty little open source project management tool called <a href='http://www.activecollab.com'>ActiveCollab</a> decided to <a href='http://www.activecollab.com/blog/37/status-update-followup/'>go commercial</a> and more or less drop the open source version. This didn&#8217;t sound too bad at the time, but as i got thinking i realised that there was a definite lack of simple project management tools which were open source. Most of those i found had clunky interfaces or a questionable development status. And of course, more or less all of them are written in PHP, not my most favourite programming language to say the least.</p>...]]></description>
		<content:encoded><![CDATA[<p>Just over 3 months ago, the developer of a a nifty little open source project management tool called <a href='http://www.activecollab.com'>ActiveCollab</a> decided to <a href='http://www.activecollab.com/blog/37/status-update-followup/'>go commercial</a> and more or less drop the open source version. This didn&#8217;t sound too bad at the time, but as i got thinking i realised that there was a definite lack of simple project management tools which were open source. Most of those i found had clunky interfaces or a questionable development status. And of course, more or less all of them are written in PHP, not my most favourite programming language to say the least.</p>
<a href='http://www.cuppadev.co.uk/wp-content/uploads/activecollab_db.jpg' title='ActiveCollab Dashboard'>
<img alt='ActiveCollab Dashboard' src='http://www.cuppadev.co.uk/wp-content/uploads/activecollab_db_t.jpg' />
</a>
<p>In the end, i was left with uncertainty of the future of ActiveCollab, so i decided to hit two bird&#8217;s with one stone and fork my own version of ActiveCollab, but this time rewrite it in Ruby using the <a href='http://www.rubyonrails.org'>Ruby on Rails</a> framework with a goal of making it open source. This seemed like a good idea at the time, as:</p>
<ol>
<li>I didn't like PHP</li>
<li>I was a bit of a novice at programming in Ruby</li>
<li>My experience of dealing with the Ruby on Rails framework was sketchy to say the least</li>
<li>ActiveCollab's PHP framework was similar to Ruby on Rails</li>
<li>Open source is great, lots of people will be interested in working on it with me</li>
</ol>
<p>The development process started as thus:</p>
<ol>
<li>I started off with a run-of-the-mill started Ruby on Rails framework project</li>
<li>I ported ActiveCollab's DB Schema over into the schema.rb</li>
<li>Using the PHP code and the schema as reference, i'd make basic Model's for each type of object used.</li>
<li>I'd decide to implement a controller</li>
<li>Using the original php code as a reference, i'd replicate the controller and its action's in the Ruby on Rails project</li>
<li>I'd also import the associated templates from ActiveCollab and convert them into .rhtml files, which are essentially the same except they use Ruby as the scripting language instead of PHP</li>
<li>Whilst trying to replicate the functionality of the controller, i'd also tweak up the related Model to fill in the gaps of missing functionality</li>
<li>In addition, when i encountered anything missing from the Ruby on Rails framework that was required, i'd find a relevant 'plugin' and import it into the project, or just implement it all by myself</li>
<li>I repeated steps 4-8 until i the majority of the functionality was implemented</li>
</ol>
<p>At first, it started out as a little pet project as mine. Though after a while, i grew a bit tired of developing it (developing in this way became very tedious and boring), and decided to push on with the open source aspect of the project and ask the ActiveCollab community if they were interested in my code. The answer i got back was <a href='http://www.activecollab.com/forums/topic/1574/'>yes</a>. And thus i decided to open it up fully to the wonderful world of open source development and placed it on <a href='http://www.rubyforge.org'>RubyForge</a>. I also decided to give it a cool name, <a href='http://rubyforge.org/projects/railscollab'>RailsCollab</a>.</p>

<p>Initially when i placed it on RubyForge i was contacted by someone who was interested in assisting. So naturally, i added them to the project. I also added another person, purported to be a friend of theirs that was also interested. Sadly though a month down the line, i received no signs of life from either of them. Its as if they thought &#8220;wow great, an open source project. lets join in!&#8221; and then promptly died from the excitement. Or maybe they just couldn&#8217;t be bothered, i don&#8217;t know.</p>

<p>So in the end being the kind person i am, i essentially did all the work myself out of the sheer hope that someone else might be interested in genuinely assisting with development. Or failing that, maybe someone would try it out and provide some much needed feedback. Sadly though, neither happened even though it was apparent at the start that people were interested.</p>
<a href='http://www.cuppadev.co.uk/wp-content/uploads/railscollab_db.jpg' title='RailsCollab Dashboard'>
<img alt='RailsCollab Dashboard' src='http://www.cuppadev.co.uk/wp-content/uploads/railscollab_db_t.jpg' />
</a>
<p>Right now, <a href='http://rubyforge.org/projects/railscollab'>RailsCollab</a> is usable as an alternative to ActiveCollab 0.7.1, with the exception of a few missing features which i have simply not got round to implementing yet. And of course it suffers from a few bugs and performance issues here and there. Still, for what it is, it works.</p>

<p>Will i ever do such a stupid thing like this again? I can conclusively say&#8230;. hell, no!</p>]]></content:encoded>
	</item>
	
	<item>
		<title>QR-Code and the quest for the elusive decoder</title>

		<link>http://www.cuppadev.co.uk/qr-code-and-the-quest-for-the-elusive-decoder/</link>
		<comments>http://www.cuppadev.co.uk/qr-code-and-the-quest-for-the-elusive-decoder/#comments</comments>
		<pubDate>Sun, 10 Jun 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=82</guid>
		<description><![CDATA[<p>After reading <a href='http://www.squidi.net/three/entry.php?id=31'>Mechanic #031</a> on the <a href='http://www.squidi.net/three/index.php'>Three Hundred game ideas</a> blog, i got thinking. Specifically, i asked myself &#8220;How easy would it be to write a web-based tool for encoding and decoding data to 2d images as pixels?&#8221;.</p><p style='text-align: center'><img alt='Barcode' src='/wp-content/uploads/barcode.png' /></p> <p>Luckily, this mechanism has been implemented before. The simplest example would be a <a href='http://en.wikipedia.org/wiki/Barcode'>barcode</a>. However, i wanted something a bit more advanced in order to pack as much data as possible into the image, as i would imagine quite a bit of information would have to be present in each &#8220;game image&#8221;. After much...]]></description>
		<content:encoded><![CDATA[<p>After reading <a href='http://www.squidi.net/three/entry.php?id=31'>Mechanic #031</a> on the <a href='http://www.squidi.net/three/index.php'>Three Hundred game ideas</a> blog, i got thinking. Specifically, i asked myself &#8220;How easy would it be to write a web-based tool for encoding and decoding data to 2d images as pixels?&#8221;.</p><p style='text-align: center'><img alt='Barcode' src='/wp-content/uploads/barcode.png' /></p>
<p>Luckily, this mechanism has been implemented before. The simplest example would be a <a href='http://en.wikipedia.org/wiki/Barcode'>barcode</a>. However, i wanted something a bit more advanced in order to pack as much data as possible into the image, as i would imagine quite a bit of information would have to be present in each &#8220;game image&#8221;. After much scouring the web, i found two promising solutions: <a href='http://en.wikipedia.org/wiki/QR_Code'>QRCode</a> and <a href='http://en.wikipedia.org/wiki/Semacode'>Semacode</a>. Sadly though, Semacode appeared to have pretty dodgy licensing, so i decided to steer clear of it and see what i could make of QRcode. <p style='text-align: center'><img alt='QRCode' src='/wp-content/uploads/qrcode.png' /></p> QRCode was interesting, as in it was very easy to find an encoder, such as <a href='http://megaui.net/fukuchi/works/qrencode/index.en.html'>libqrencode</a>. Unfortunately, it was very difficult finding a decoder that didn&#8217;t just run on a mobile phone (which seems to be a popular way of decoding QRCode&#8217;s). The only standalone library that could decode was written in java, oddly enough also called <a href='http://qrcode.sourceforge.jp/'>qrcode</a>.</p>
<p>To be honest, i&#8217;m a bit put off of proceeding any further trying to get this question answered, mainly because everything seems to be written in Java, &#8211; which is fair enough, but considering my skills in programming Java are minimal, i might end up with a rather dodgy botched together solution.</p><p>Regardless, i think the concept of deciphering data from 2d images is neat. I&#8217;ll just have to find the elusive c-based decoder for QCode, or perhaps even better, find a better supported alternative system.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>Javascript Draw</title>

		<link>http://www.cuppadev.co.uk/javascript-draw/</link>
		<comments>http://www.cuppadev.co.uk/javascript-draw/#comments</comments>
		<pubDate>Sat, 02 Jun 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=80</guid>
		<description><![CDATA[<p>Quite a while ago when i embarked on the <a href='http://www.cuppadev.co.uk/2007/05/19/the-javascript-bandwagon/'>Javascript Bandwagon</a>, one of the first things i implemented was a rather simple draw test which plotted a few rectangles and other primitives on a <a href='http://www.whatwg.org'>WhatWG</a> canvas object.</p><p>One of the little problems i encountered with the WhatWG canvas was that you really needed to play around with the values for the control points on such things as arc&#8217;s and bezier curves in order to get the result you wanted. Either that, or draw everything in a vector based drawing tool and convert it to the appropriate set of drawing...]]></description>
		<content:encoded><![CDATA[<p>Quite a while ago when i embarked on the <a href='http://www.cuppadev.co.uk/2007/05/19/the-javascript-bandwagon/'>Javascript Bandwagon</a>, one of the first things i implemented was a rather simple draw test which plotted a few rectangles and other primitives on a <a href='http://www.whatwg.org'>WhatWG</a> canvas object.</p><p>One of the little problems i encountered with the WhatWG canvas was that you really needed to play around with the values for the control points on such things as arc&#8217;s and bezier curves in order to get the result you wanted. Either that, or draw everything in a vector based drawing tool and convert it to the appropriate set of drawing commands to feed into the canvas object.</p><p>Safe to say, i wasn&#8217;t so easily defeated by this little problem, and so i had a crazy idea: would it be possible to create a drawing tool <strong>written entirely in javascript</strong> which used the canvas object?</p><p>The first implementation of the JavaScript drawing tool (which i will now refer to as <span class='caps'>JSDT</span>) resembled frankenstein on steroids. I didn&#8217;t completely understand how JavaScript&#8217;s &#8220;classes&#8221; worked, so it was more or less a bunch of hap-hazardly designed functions all placed in the global namespace. Whilst it worked, it was <strong>hell to maintain</strong>, plus it lacked crucial features such as the ability to rotate and scale objects &#8211; as well as group them hierarchically.</p><p>For reference, <a href='/wp-content/uploads/test_draw/first.html'>here is a copy</a> of the first version for you to laugh at. Note though that everything (including the manipulators) is handled in the little WhatWG canvas &#8211; no <span class='caps'>DOM</span> in sight!</p><p>For the second version i decided to use classes from the ground-up, and make use of one of the various javascript toolkit&#8217;s available. In the end i chose <a href='http://www.mootools.net/'>Mootools</a>, on account of it being lightweight and seemingly faster than the other framework&#8217;s i tried. I also <strong>planned out the design</strong> from the beginning, which helped a lot.</p><p>The second version sadly ended up being the third, as half-way through i realized that i wasn&#8217;t using the mootools &#8220;Class&#8221; object correctly. In error, i assumed attaching function&#8217;s to Classes was a bit of a memory intensive operation, and thus i decided to eliminate functions from the <span class='caps'>JSDT</span>&#8217;s canvas objects, and instead place them in an &#8220;ObjectHelper&#8221; class.</p><p>Soon after, i realized how stupid i was, considering the functions are actually assigned to the object&#8217;s prototype &#8211; not its instance &#8211; and thus would be shared between each instance of the class.
And thus, &#8220;ObjectHelper&#8221; was obliterated. A good thing too, as i noticed a big speed boost! I guess it just goes to show how much slower it is to use &#8220;this.object_helper.do_that(object);&#8221; rather than the more concise &#8220;object.do_that();&#8221;.</p><p>For reference, <a href='/wp-content/uploads/test_draw/index.html'>here is a copy</a> of the third version. Its much improved over the first, and you can even change the selected object&#8217;s style properties via the nice toolbox. Sadly, i haven&#8217;t yet got round to implementing the &#8220;Save&#8221; and &#8220;Load&#8221; functions, which would be the next major step in implementing the <span class='caps'>JSDT</span> &#8211; shouldn&#8217;t be too hard to write out the canvas object list as <span class='caps'>JSON</span> and send it to / from the server.</p>
<p>Safe to say, i learned a lot about the peculiarities of JavaScript when making the various iterations of the <span class='caps'>JSDT</span>. I also experienced first hand how utterly annoying it is to have code work perfectly in one browser, yet fail <strong>miserably</strong> in the other. One interesting issue i did find with regard to the WhatWG canvas was that Apple&#8217;s Safari browser couldn&#8217;t quite handle this code:</p>

<pre><code>...
canvas.moveTo(10,10);
canvas.beginPath();
canvas.lineTo(20, 10);
canvas.lineTo(20, 20);
canvas.lineTo(10, 20);
canvas.closePath();
canvas.fill();
canvas.stroke();
...</code></pre>

<p>In Firefox, Mozilla, and Opera this would draw a little filled in square with a line border. In Safari however, it draws a filled in square <strong>without</strong> a line border! It seems that Safari completely forgets about the path after you either fill or stroke it, so the only workaround is to just plot the path again, i.e.:</p>

<pre><code>...
canvas.moveTo(10,10);
canvas.beginPath();
canvas.lineTo(20, 10);
canvas.lineTo(20, 20);
canvas.lineTo(10, 20);
canvas.closePath();
canvas.fill();
// +++
canvas.beginPath();
canvas.lineTo(20, 10);
canvas.lineTo(20, 20);
canvas.lineTo(10, 20);
canvas.closePath();
// +++
canvas.stroke();
...</code></pre>

<p>&#8230;which as you can imagine is much slower, especially if you are drawing lots of primitives!</p>
<p>For my next rewrite of the <span class='caps'>JSDT</span>, i think i might look at implementing it in an abstraction layer such as <a href='http://www.openlaszlo.org/'>OpenLazlo</a> or the <a href='http://code.google.com/webtoolkit/'>Google Web Toolkit</a>. Hopefully then i will be able to eliminate much of the manual workarounds i have had to hack in, instead leaving it to a nice automated tool.</p>]]></content:encoded>
	</item>
	
	<item>
		<title>rm -rf</title>

		<link>http://www.cuppadev.co.uk/rm-rf/</link>
		<comments>http://www.cuppadev.co.uk/rm-rf/#comments</comments>
		<pubDate>Sat, 26 May 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=78</guid>
		<description><![CDATA[<p>A short while ago, i was having problems uploading files in wordpress. It seems that it was trying to write to /tmp, even though in my php configuration the clearly specifies the upload directory to be something completely different.</p><p>During the process of basically trying to solve this issue, i decided to have a little spring clean and remove some unneccesary redundant folders from my web server directory, which is when i typed in the following:</p><pre>rm -rf htdocs</pre> <p>Safe to say, i wasn&#8217;t very pleased with the results. Not to mention, i haven&#8217;t done any recent backup&#8217;s, so my lovely customized...]]></description>
		<content:encoded><![CDATA[<p>A short while ago, i was having problems uploading files in wordpress. It seems that it was trying to write to /tmp, even though in my php configuration the clearly specifies the upload directory to be something completely different.</p><p>During the process of basically trying to solve this issue, i decided to have a little spring clean and remove some unneccesary redundant folders from my web server directory, which is when i typed in the following:</p><pre>rm -rf htdocs</pre>
<p>Safe to say, i wasn&#8217;t very pleased with the results. Not to mention, i haven&#8217;t done any recent backup&#8217;s, so my lovely customized version of wordpress more or less vanished in an instant.</p>
<p>The good news however is that i managed to more or less get everything working again. I even took the time to upgrade to the latest version of wordpress (which even included the sidebar widget functionality, which left me with one less thing to install).</p><p>So i guess the motto of this story is: <strong><span class='caps'>BACKUP</span>! BACKUP! <span class='caps'>BACKUP</span>!</strong></p><p>Until next time&#8230;</p>]]></content:encoded>
	</item>
	
	<item>
		<title>The JavaScript Bandwagon</title>

		<link>http://www.cuppadev.co.uk/the-javascript-bandwagon/</link>
		<comments>http://www.cuppadev.co.uk/the-javascript-bandwagon/#comments</comments>
		<pubDate>Sat, 19 May 2007 00:00:00 BST</pubDate>
		<dc:creator>James Urquhart</dc:creator>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=76</guid>
		<description><![CDATA[<p>A few month's ago, i decided to hop on the Javascript bandwagon. I wanted to find out what it could do, how well it could do it, and what limitations i would bump into.</p><p>What i discovered was not what i expected.</p><h3>Incompatibility</h3><p>First and foremost, one of the first problems one bump's into with javascript is that all the major web browsers implement it differently. Code can work perfectly in one browser and fail miserably in another. For example:</p><code> var myList = { tea: 1, coffee: 2, }; </code><p>Seems perfectly fine to me. In fact, it worked fine in Firefox. However, it...]]></description>
		<content:encoded><![CDATA[<p>A few month's ago, i decided to hop on the Javascript bandwagon. I wanted to find out what it could do, how well it could do it, and what limitations i would bump into.</p><p>What i discovered was not what i expected.</p><h3>Incompatibility</h3><p>First and foremost, one of the first problems one bump's into with javascript is that all the major web browsers implement it differently. Code can work perfectly in one browser and fail miserably in another. For example:</p><code>
var myList = {
tea: 1,
coffee: 2,
};
</code><p>Seems perfectly fine to me. In fact, it worked fine in Firefox. However, it didn't work in Safari, Apple's flagship browser. The only clue in the JavaScript console i got was "SyntaxError - parse error", which eventually led me to this solution:</p><code>
var myList = {
tea: 1,
coffee: 2
};
</code><p>Yes that's right... all that fuss was over a single little comma.</p><h3>Simple? Not!</h3><p>After figuring that Javascript was a pretty simple c-style programming language, i thought i had it all figured out.</p><pre class='markdown-html-error' style='border: solid 3px red; background-color: pink'>REXML could not parse this XML/HTML: 
&lt;p&gt;However, after checking out Dogulas Crockford&apos;s presentation &quot;&lt;a href=&quot;http://video.yahoo.com/video/play?ei=UTF-8&amp;b=26&amp;vid=111593&amp;gid=133414&quot;&gt;The JavaScript Programming Language&lt;/a&gt;&quot;, i was left a bit dumbfounded. What i thought was a simple boring run-of-the-mill scripting language was in fact a pretty extensible and interesting programming language. Neat!&lt;/p&gt;</pre><h3>Frameworks</h3><p>The first time i tried writing something in JavaScript, i decided to go "all-pro" and not use any of the numerous development frameworks that have popped up over the years. This was a big mistake.</p><p>After a long period of writing everything from scratch (whilst only half knowing what on earth i was doing i might add), i stumbled across the <a href='http://mootools.net'>mootools</a> framework.</p><p>Selecting elements? simple. Handling events? simple. Making complex object-oriented front-end's? simple. Having it all work in every major web browser? priceless. In fact, pretty much everything was <b>ten times easier to work with</b>, and solutions took <b>less than half the time</b> to be implemented.</p><h3>Slow, yet fast, yet slow</h3><p>Sadly, since JavaScript does not have a single implementation, <b>performance varies</b> a lot between browsers. For simple things, the difference was hardly noticeable. For more complex things though (e.g. interfacing with the <a href='http://developer.mozilla.org/en/docs/Drawing_Graphics_with_Canvas'>WhatWG canvas</a>), differences definitely became much more noticeable, although i would not like to speculate which browser has the fastest implementation of JavaScript as i have not done any conclusive benchmarks yet.</p><h3>Single Threaded</h3><p>Sadly for the most part, there is no support for threading in JavaScript. You can only do one thing at once. Whilst this is not a bad idea, it does become a little bit of a problem if you are running multiple time-out's and intervals. Everything has to wait for its turn in line so to speak, which is pretty much bad news if you really want something to happen in X amount of time, irrespective of whatever else happens in-between...</p><p>...oh well, i guess i can live with it.</p><p>Safe to say, i'll be <i>experimenting</i> a bit more with JavaScript in the future.</p>]]></content:encoded>
	</item>
	
</channel>
</rss>
