<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>ggml/&#62;</title>
	<atom:link href="http://gabrielegenta.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://gabrielegenta.wordpress.com</link>
	<description>web experience, technology and more</description>
	<lastBuildDate>Fri, 26 Aug 2011 21:09:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='gabrielegenta.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>ggml/&#62;</title>
		<link>http://gabrielegenta.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://gabrielegenta.wordpress.com/osd.xml" title="ggml/&#62;" />
	<atom:link rel='hub' href='http://gabrielegenta.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Calliope First Run</title>
		<link>http://gabrielegenta.wordpress.com/2011/06/12/calliope-first-run/</link>
		<comments>http://gabrielegenta.wordpress.com/2011/06/12/calliope-first-run/#comments</comments>
		<pubDate>Sun, 12 Jun 2011 10:58:02 +0000</pubDate>
		<dc:creator>Gabriele Genta</dc:creator>
				<category><![CDATA[Calliope]]></category>
		<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://gabrielegenta.wordpress.com/?p=298</guid>
		<description><![CDATA[In past weeks I put online an experimental version of Calliope and tested it out by playing real games with friends. Unfortunately, it didn&#8217;t performed that well. I identified a set of technical problems, and a set of design ones. &#8230; <a href="http://gabrielegenta.wordpress.com/2011/06/12/calliope-first-run/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=298&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In past weeks I put online an experimental version of Calliope and tested it out by playing real games with friends. Unfortunately, it didn&#8217;t performed that well. I identified a set of technical problems, and a set of design ones.<br />
<span id="more-298"></span><br />
Here are the technicals:</p>
<ul>
<li>real time view of the opponent&#8217;s actions isn&#8217;t working at all, probably due to the increased delay in communication with the server;</li>
<li>the game is very heavy on the CPU (around 90% on my Core 2 Duo when moving letters around);</li>
<li>animations are kinda messy and not always executed at the right times;</li>
<li>overall it is quite unstable, crashed often during tests (although reloading worked very well and never lost a move).</li>
</ul>
<p>On the design side, I found the game to be too plain and, honestly, quite boring. I concentrated much of my programming effort in making the game board work and less on creating an immersive game experience, which I think is what Calliope lacks right now. Maybe this can be corrected by adding more information on what is going on than just the turn number and the name of the user playing; anyway, I&#8217;ll have to look into this carefully and maybe sketch some mockups.</p>
<p>To counterbalance the technical problems I&#8217;m afraid I will have to do some radical changes in the implementation. To achieve better responsiveness I&#8217;ll have a look at how other real time applications handle it (I&#8217;m having a look for example at long-polling mechanisms like Comet); in order to decrease CPU usage and gain better control on animations I&#8217;ll have to leave SVG and Raphael and turn to HTML5 Canvas, maybe by using some javascript game development framework. Last but not least: instability, I will have to fight it with better design and thorough testing.</p>
<p>The road ahead is longer than expected, but I certainly still want to pull this off.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gabrielegenta.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gabrielegenta.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gabrielegenta.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gabrielegenta.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gabrielegenta.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gabrielegenta.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gabrielegenta.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gabrielegenta.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gabrielegenta.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gabrielegenta.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gabrielegenta.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gabrielegenta.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gabrielegenta.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gabrielegenta.wordpress.com/298/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=298&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gabrielegenta.wordpress.com/2011/06/12/calliope-first-run/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ada143e6c93581ebcbcf510187c13908?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielegenta</media:title>
		</media:content>
	</item>
		<item>
		<title>Calliope &#8211; Preview 1 ToDo</title>
		<link>http://gabrielegenta.wordpress.com/2011/05/08/calliope-pr1-todo/</link>
		<comments>http://gabrielegenta.wordpress.com/2011/05/08/calliope-pr1-todo/#comments</comments>
		<pubDate>Sun, 08 May 2011 09:33:17 +0000</pubDate>
		<dc:creator>Gabriele Genta</dc:creator>
				<category><![CDATA[Calliope]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[screenshots]]></category>
		<category><![CDATA[todo]]></category>

		<guid isPermaLink="false">http://gabrielegenta.wordpress.com/?p=238</guid>
		<description><![CDATA[Here is a brief list of what must be done before the release of the first preview of Calliope: Fix some bugs in the board related to z-order and overlapping; Redesign the game-choosing screen; (see screenshot below) Provide a button &#8230; <a href="http://gabrielegenta.wordpress.com/2011/05/08/calliope-pr1-todo/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=238&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Here is a brief list of what must be done before the release of the first preview of Calliope:</p>
<ul>
<li><del>Fix some bugs in the board related to z-order and overlapping;</del></li>
<li><del>Redesign the game-choosing screen;</del> (see screenshot below)</li>
<li>Provide a button to create a new game;</li>
<li>Provide a simple registration interface for new users.</li>
</ul>
<p>I am going to document every step forward in this post, adding short comments and striking off items as soon as I implement them.</p>
<p><strong>Update 12/6/2011 -</strong> Online preview of Calliope has been delayed after a set of private tests gave not-so-encouraging results, <a title="Calliope First Run" href="http://gabrielegenta.wordpress.com/2011/06/12/calliope-first-run/">read here for more</a>.</p>
<p><strong>Update 9/5/2011 -</strong> The new front screen of the application:<a href="http://gabrielegenta.files.wordpress.com/2011/04/pr0_frontscreen.png"><img class="aligncenter size-full wp-image-293" title="Front Screen" src="http://gabrielegenta.files.wordpress.com/2011/04/pr0_frontscreen.png?w=584&#038;h=393" alt="" width="584" height="393" /></a><br />
In a future version, the icons on the left will depict the current progress of the game.</p>
<p><strong>Would you like to join development? </strong><a title="Contacts" href="http://gabrielegenta.wordpress.com/about/" target="_blank">Let me know!</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gabrielegenta.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gabrielegenta.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gabrielegenta.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gabrielegenta.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gabrielegenta.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gabrielegenta.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gabrielegenta.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gabrielegenta.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gabrielegenta.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gabrielegenta.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gabrielegenta.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gabrielegenta.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gabrielegenta.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gabrielegenta.wordpress.com/238/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=238&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gabrielegenta.wordpress.com/2011/05/08/calliope-pr1-todo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ada143e6c93581ebcbcf510187c13908?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielegenta</media:title>
		</media:content>

		<media:content url="http://gabrielegenta.files.wordpress.com/2011/04/pr0_frontscreen.png" medium="image">
			<media:title type="html">Front Screen</media:title>
		</media:content>
	</item>
		<item>
		<title>Building Calliope &#8211; Sproutcore data sources (Part III)</title>
		<link>http://gabrielegenta.wordpress.com/2011/04/27/calliope-data-sources-p3/</link>
		<comments>http://gabrielegenta.wordpress.com/2011/04/27/calliope-data-sources-p3/#comments</comments>
		<pubDate>Wed, 27 Apr 2011 08:22:03 +0000</pubDate>
		<dc:creator>Gabriele Genta</dc:creator>
				<category><![CDATA[Calliope]]></category>
		<category><![CDATA[data-sources]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[restful]]></category>
		<category><![CDATA[Sproutcore]]></category>

		<guid isPermaLink="false">http://gabrielegenta.wordpress.com/?p=257</guid>
		<description><![CDATA[« Go to Part II Game (aka Local) data source (..continues from Part II) Before going further, let&#8217;s recap what data the application has to deal with during its operations: The last turn of the selected game, along with its &#8230; <a href="http://gabrielegenta.wordpress.com/2011/04/27/calliope-data-sources-p3/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=257&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://gabrielegenta.wordpress.com/2011/04/27/calliope-data-sources-p2/" title="Building Calliope – Sproutcore data sources (Part II)">« Go to Part II</a></p>
<h2>Game (aka Local) data source (..continues from Part II)</h2>
<p>Before going further, let&#8217;s recap what data the application has to deal with during its operations:</p>
<ol>
<li>The last turn of the selected game, along with its letters&#8217; configuration (service <code>*/turns/{number}</code>);</li>
<li>The list of pivotal actions belonging to the game and to its last turn (service <code>*/actions?pivotOnly&amp;turn={turnNumber}</code>);</li>
<li>Periodically, the list of new actions to perform (service <code>*/actions?afterAction={actionId}</code>).</li>
</ol>
<p>where * stands for <code>/me/games/{id}</code>.</p>
<p>The first item &#8211; related to the current turn and letters &#8211; has been pointed out in <a href="http://gabrielegenta.wordpress.com/2011/04/27/calliope-data-sources-p2/" title="Building Calliope – Sproutcore data sources (Part II)">Part II</a>. In this part I&#8217;m going to dig deeper into the last two points.<br />
<span id="more-257"></span></p>
<p>The second and third point of the list are threatened in a uniform way, with the usage of a <strong>remote query</strong>. </p>
<div style="padding-left:20px;">
Remote queries differ from local ones in many ways, here are the ones I was able to understand:</p>
<ul>
<li>everytime a remote query is issued (with a call to <code>find</code> on the data store), the <code>fetch</code> method is invoked in the data source &#8211; in the case of a local query, instead, <code>fetch</code> is invoked only the first time the query is issued;</li>
<li>the results of a remote query are explicitly set by the code handling the fetch &#8211; in the case of a local query, the code handling the fetch has only the responsibility of loading records into the store, the retrieval part is done internally by Sproutcore.</li>
</ul>
<p>Basically, local queries are handled by Sproutcore internally, they&#8217;re sort of filters on the data already contained in the store, whereas remote queries are handled by user code, and are a way to retrieve new data from the server, retaining full control over what is retrieved as a result.
</p></div>
<p>Given the information above, remote queries where the choice to go for action retrieval. I started by declaring two static methods in <code>Calliope.Action</code> to act as helpers in creating the queries themself; each method supporting one of the points above:</p>
<pre class="brush: jscript;">
Calliope.Action.query_PIVOT = function(turnNumber) {
  return SC.Query.remote(Calliope.Action, {pivotOnly: YES, turn: turnNumber});
};
Calliope.Action.query_LIVE = function(lastActionId) {
  return SC.Query.remote(Calliope.Action, {afterAction: lastActionId});
};
</pre>
<p>The creation of queries is really straightforward, you can fill an object with all the information you need in the fetching phase and pass it as the second argument of <code>SC.Query.remote</code>. In the first example I&#8217;m passing in the flag <code>pivotOnly</code> and the number of the turn to retrieve (case 1 above); in the other example I&#8217;m passing just the id of the last seen action as <code>afterAction</code> (case 2 above). </p>
<p>Let&#8217;s now have a look at how these queries are used inside the application. The usage is really simple:</p>
<pre class="brush: jscript;">
(case 1)
var actions = store.find(Calliope.Action.query_PIVOT(currentGame.get(&quot;turnCount&quot;)))

(case 2)
var actions = store.find(Calliope.Action.query_LIVE(lastSeenActionId))
</pre>
<p>When the <code>find</code> method is issued, as stated above, Sproutcore invokes the <code>fetch</code> method in the data source, passing along the query that was issued. The implementation of that method must provide an explicit result for the query. Here is the implementation part relative to the queries on Action:</p>
<pre class="brush: jscript;">
  fetch: function(store, query) {
    // check whether the query is a remote query on Calliope.Action
    if (query.get(&quot;isRemote&quot;) &amp;&amp; query.get(&quot;recordType&quot;) === Calliope.Action) {
      // build the url with parameters afterAction, pivotOnly and afterAction
      var url = &quot;/actions&quot;;
      var reqQuery = [];
      if (!SC.none(query.afterAction)) {
        reqQuery.pushObject(&quot;afterAction=%@&quot;.fmt(query.afterAction));
      }
      if (!SC.none(query.turn)) {
        reqQuery.pushObject(&quot;turn=%@&quot;.fmt(query.turn));
      }
      if (query.pivotOnly) {
        reqQuery.pushObject(&quot;pivotOnly&quot;);
      }
      if (reqQuery.length &gt; 0) {
        url += &quot;?&quot; + reqQuery.join(&quot;&amp;&quot;);
      }

      // issue the remote request
      Calliope.session.createRequest({
        address: this.getUrl(url)
      }).notify(this, this._didFetchActions, store, query)
      .send();
      return YES;
    }

    return NO;
  }
</pre>
<p>The method checks the query to see if it is remote and is relative to <code>Calliope.Action</code>, and then uses the parameters passed to the query (which, as you can notice, are accessible directly in <code>query</code>) in order to build the full url of the remote request. In the first case the url would look like this:</p>
<pre>/actions?turn={query.turnNumber}&amp;pivotOnly</pre>
<p>whilst in the second case it would look like this:</p>
<pre>/actions?afterAction={query.afterAction}</pre>
<p>As seen in Part II, the url is then completed by calling <code>getUrl</code> (line 22), which prepends <code>/me/games/{gameId}</code> to it.</p>
<p>Each of the service calls above return a list of actions similar to the following one (more details <a href="http://gabrielegenta.wordpress.com/2011/04/11/calliope-services-design/" title="Building Calliope – Services Design">here</a>):</p>
<pre>[
  {
    "type":"letter_drag_end",
    "attributes":"{ ... }",
    "time":"2011-04-08 09:05:00",
    "t":"1302246300040",
    "actionId":24456,
    "pivot":true,
    "player":1
  },
  ...
]</pre>
<p>This data is then passed to the notify method <code>_didFetchActions</code> which is in charge of loading it into the store as a series of <code>Calliope.Action</code>s, and of explicitly setting the results of the query. Here is the implementation:</p>
<pre class="brush: jscript;">
  _didFetchActions: function(response, store, query) {
    var body = this._getResponseBody(response, store, query);
    if (!SC.none(body)) {
      // load the actions into the store to retrieve the store keys
      var storeKeys = store.loadRecords(Calliope.Action, body);
      // load query results
      store.loadQueryResults(query, storeKeys);
    }
  }
</pre>
<p>As you can see there is nothing complicated here. The two steps described above are handled literally by two lines of code. The first call to <code>loadRecords</code> loads the server data into the store as <code>Calliope.Action</code> instances and receives, as a result, the list of the associated store keys; the second call to <code>loadQueryResults</code> does nothing but explicitly setting the results for the query, which finally gets accessible to the caller of <code>find</code>.</p>
<p>As already pointed out in Part II, the call to the server happens asynchronously, so the list of actions retrieved that way isn&#8217;t already available at the end of the call to <code>find</code>. What is returned is an instance of <code>SC.RecordArray</code> with an empty <code>storeKeys</code> variable. By observing the array for changes you can be notified when data is ready to be used; here is an example on how to do it:</p>
<pre class="brush: jscript;">
Calliope.SomeObject = SC.Object.extend({
  _actionsArray: null,
  loadActions: function() {
    this._actionsArray = store.find(Calliope.Action.query_LINE(15));
  },
  _actionsArrayDidChange() {
    if (!SC.none(this._actionsArray.storeKeys)) {
      // DO STUFF
    }
  }.observes(&quot;*_actionsArray.[]&quot;)
});
</pre>
<h2>Last note</h2>
<p>This is the end of my first article about the basics of Sproutcore data sources. Hope you liked it and if you did &#8211; or didn&#8217;t &#8211; please drop a line.</p>
<p>There is more about data sources I would have liked to share, in particular the usage of <code>chain</code> to create nested data stores, and the handling of data saving; I&#8217;m planning a series of articles about those subjects as well, if you are interested just let me know.</p>
<p>There is also one open point I have not faced yet in the application but I will eventually have to: what&#8217;s the right way of refreshing the data store for &#8220;global&#8221; data like games and players? (for example in order to know that a new game has been created, or a new player has registered).</p>
<p><a href="http://gabrielegenta.wordpress.com/2011/04/27/calliope-data-sources-p2/" title="Building Calliope – Sproutcore data sources (Part II)">« Go to Part II</a><br />
<a title="Building Calliope – Index" href="http://gabrielegenta.wordpress.com/2011/03/21/building-calliope-index/">« Go back to the index</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gabrielegenta.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gabrielegenta.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gabrielegenta.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gabrielegenta.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gabrielegenta.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gabrielegenta.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gabrielegenta.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gabrielegenta.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gabrielegenta.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gabrielegenta.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gabrielegenta.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gabrielegenta.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gabrielegenta.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gabrielegenta.wordpress.com/257/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=257&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gabrielegenta.wordpress.com/2011/04/27/calliope-data-sources-p3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ada143e6c93581ebcbcf510187c13908?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielegenta</media:title>
		</media:content>
	</item>
		<item>
		<title>Building Calliope &#8211; Sproutcore data sources (Part II)</title>
		<link>http://gabrielegenta.wordpress.com/2011/04/27/calliope-data-sources-p2/</link>
		<comments>http://gabrielegenta.wordpress.com/2011/04/27/calliope-data-sources-p2/#comments</comments>
		<pubDate>Wed, 27 Apr 2011 08:16:46 +0000</pubDate>
		<dc:creator>Gabriele Genta</dc:creator>
				<category><![CDATA[Calliope]]></category>
		<category><![CDATA[data-sources]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[restful]]></category>
		<category><![CDATA[Sproutcore]]></category>

		<guid isPermaLink="false">http://gabrielegenta.wordpress.com/?p=211</guid>
		<description><![CDATA[Go to Part III &#187; « Go to Part I Game (aka Local) data source In the local scenario the user has logged in, has selected one of its open games (which list if handled by the global data source) &#8230; <a href="http://gabrielegenta.wordpress.com/2011/04/27/calliope-data-sources-p2/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=211&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>
<div style="float:right;"><a href="http://gabrielegenta.wordpress.com/2011/04/27/calliope-data-sources-p3/" title="Building Calliope – Sproutcore data sources (Part III)">Go to Part III &raquo;</a></div>
<div><a href="http://gabrielegenta.wordpress.com/2011/04/17/calliope-data-sources-p1/" title="Building Calliope – Sproutcore data sources (Part I)">« Go to Part I</a></div>
</p>
<h2>Game (aka Local) data source</h2>
<p>In the local scenario the user has logged in, has selected one of its open games (which list if handled by the global data source) and is taken to the board in order to be able to play the game. In this scenario, the application must load the current game state (that is, the position of all the letters in the game), present it to the user and update it continuously, replicating the actions of the other players.</p>
<p>Notice that this task is more complicated, and cannot be solved using the &#8220;load-all-retrieve-by-id&#8221; approach used previously: the data involved is potentially quite big (imagine a game with a hundred turns, for example) and could take more than a while to load; actions are pumped in continuously, and as such cannot be loaded once and for all, but must be refreshed constantly.<br />
<span id="more-211"></span></p>
<p>In order to reduce bandwidth usage and loading times, here is what the application has to load in detail:</p>
<ol>
<li>The last turn of the selected game, along with its letters&#8217; configuration (service <code>*/turns/{number}</code>);</li>
<li>The list of pivotal actions belonging to the game and to its last turn (service <code>*/actions?pivotOnly&amp;turn={turnNumber}</code>);</li>
<li>Periodically, the list of new actions to perform (service <code>*/actions?afterAction={actionId}</code>).</li>
</ol>
<p>where * stands for <code>/me/games/{id}</code>.</p>
<p>Notice that in doing this, the application loads from the server only relevant data, not the whole dataset. In order to handle this scenario effectively, in a modular way &#8211; and given that each and every service call above includes a game id &#8211; I decided to write separate data source, that I called (surprisingly) GameDataSource.</p>
<h3>Creation</h3>
<p>An instance of GameDataSource is created as soon as a game id is available, that is, when the user has selected the game to play. The new data source is then cascaded to the global one and assigned to the data store. This way, every request issed to the data store is forwarded to the game data source first, and to the global data source as a second try.</p>
<p><a href="http://gabrielegenta.files.wordpress.com/2011/04/cascade-data-store.png"><img class="aligncenter size-full wp-image-246" title="Cascade Data Store" src="http://gabrielegenta.files.wordpress.com/2011/04/cascade-data-store.png?w=584&#038;h=194" alt="A schema of the cascade data store" width="584" height="194" /></a></p>
<p>In order to build such a structure, the following code is used:</p>
<pre class="brush: jscript;">
Calliope.store.cascade(Calliope.GameDataSource.create({
    gameId: selectedGameId
  }), Calliope.store.get(&quot;dataSource&quot;));
</pre>
<h3>Implementation</h3>
<p>With reference to the three above points let&#8217;s have a look at what requests are issued to the data store and how they&#8217;re handled by the GameDataSource.</p>
<p><em>(1) The last turn of the selected game, along with its letters&#8217; configuration</em></p>
<p>The application already has the number of the last turn of the selected game: it is found in the <em>turnCount</em> field of the game model itself. So, loading in a specified turn is only a matter of issuing a direct find by id:</p>
<pre>store.find(Calliope.Turn, currentGame.get("turnCount"));</pre>
<p>This call is similar to the ones used for the global portion of data, but since in this case we don&#8217;t preload records through a query, the data source cannot contain the requested record. All this translates to a call to the <code>retrieveRecord</code> method in the data source. The <code>retrieveRecord</code> method is called every time the data source must load a record by id (which can happen by a direct call as above, or by the automatic following of a relationship) and it doesn&#8217;t have a copy of that record already available. Here is the implementation of <code>retrieveRecord</code>:</p>
<pre class="brush: jscript;">
  retrieveRecord: function(store, storeKey, id) {
    // retrieve the id from the storeKey
    if (SC.none(id)) {
      id = SC.Store.idFor(storeKey);
    }
    // retrieve the record type
    var recordType = store.recordTypeFor(storeKey);
    if (Calliope.Turn === recordType) {
      Calliope.session.createRequest({
        address: this.getUrl(&quot;/turns/%@&quot;.fmt(id))
      })
      .notify(this, this._retrieveRecordDidComplete, recordType, store, storeKey)
      .send();
      return YES;
    }
    return sc_super();
  }
</pre>
<p>The implementation is pretty straightforward: if the find request is related to a turn (<code>Calliope.Turn</code> record type), a GET is sent to the URL <code>/turns/{id}</code>, where {id} is the parameter passed in the call to <code>find</code>, that is: the turn number. The method <code>getUrl</code> is a simple utility method that prepends </code>/me/games/{gameId}</code> to the passed string; in the example above, the full URL becomes: <code>/me/games/{gameId}/turns/{id}</code>.<br />
The service call above returns the turn information along with its letters (details <a href="http://gabrielegenta.wordpress.com/2011/04/11/calliope-services-design/" title="Building Calliope – Services Design">here</a>), in the following form:</p>
<pre>{
  "time":"2011-03-11 21:56:44",
  "ended":false,
  "player":1,
  "turnNumber":1,
  "letters": [
    { "id":10369, "lid":1, "l":"A", "c":"s" },
    { "id":10370, "lid":2, "l":"A", "c":"s" },
    ...
  ]
}</pre>
<p>This data is passed to the notify method <code>_retrieveRecordDidComplete</code>, which is in charge of decoding it and loading it into the store as one <code>Calliope.Turn</code> entity and a number of related <code>Calliope.TurnLetter</code>s. Here is the code:</p>
<pre class="brush: jscript;">
  _retrieveRecordDidComplete: function(response, recordType, store, storeKey) {
    var body = this._getResponseBody(response, storeKey);
    if (!SC.none(body)) {
      if (recordType === Calliope.Turn) {
        // load turn letters
        var letters = body.letters;
        // replace body letters with just the ids
        body.letters = letters.map(function(letterDescr) {
          return letterDescr.id;
        });
        // fill letters with the turn reference
        for (var i = 0; i &lt; letters.length; i++) {
          letters[i].turn = body.turnNumber;
        }
        // load letters into the store
        store.loadRecords(Calliope.TurnLetter, letters);
      }
      // load record into the store
      store.loadRecord(recordType, body, body.turnNumber);
    }
  }
</pre>
<p>Sproutcore expects related records to be expressed as a list of ids; the <code>letters</code> field of the data structure above is not in the expected format, because it contains the whole objects instead of just the ids. What the <code>_retrieveRecordDidComplete</code> essentially does is extracting the list of letters from the original data structure, pre-loading them into the store with a call to <code>loadRecords</code> and then replacing them into the original structure with the list of the ids only. After doing that, the data structure is then in the format that Sproutcore expects, and can be loaded directly into a record of type <code>Calliope.Turn</code>. And this is everything that must be done in order to load the turn.</p>
<p>Notice that the call to the server takes place asynchronously, so the turn record cannot be returned immediately after the call to the initial <code>find</code>. What is instead returned is an empty <code>SC.Record</code> in state <code>BUSY_LOADING</code>, that you can observe in order to know when the data is ready to be used, like this:</p>
<pre class="brush: jscript;">
  var turn = this.get(&quot;store&quot;).find(Calliope.Turn, currentGame.get(&quot;turnCount&quot;));
  // add a status observer to the record
  turn.addObserver('status', this, function() {
    if (turn.get('status') === SC.Record.READY_CLEAN) {
      // remove the status observer
      turn.removeObserver('status', this, arguments.callee);
      // DO STUFF
    }
  });
</pre>
<p><strong>End of Part II</strong></p>
<p>If you read this far please take the time to leave a comment to let me know what you liked, what you didn’t, and what you would do differently. Thank you.</p>
<div style="float:right;"><a href="http://gabrielegenta.wordpress.com/2011/04/27/calliope-data-sources-p3/" title="Building Calliope – Sproutcore data sources (Part III)">Go to Part III &raquo;</a></div>
<div><a href="http://gabrielegenta.wordpress.com/2011/04/17/calliope-data-sources-p1/" title="Building Calliope – Sproutcore data sources (Part I)">« Go to Part I</a></div>
<p><a title="Building Calliope – Index" href="http://gabrielegenta.wordpress.com/2011/03/21/building-calliope-index/">« Go back to the index</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gabrielegenta.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gabrielegenta.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gabrielegenta.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gabrielegenta.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gabrielegenta.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gabrielegenta.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gabrielegenta.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gabrielegenta.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gabrielegenta.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gabrielegenta.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gabrielegenta.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gabrielegenta.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gabrielegenta.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gabrielegenta.wordpress.com/211/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=211&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gabrielegenta.wordpress.com/2011/04/27/calliope-data-sources-p2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ada143e6c93581ebcbcf510187c13908?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielegenta</media:title>
		</media:content>

		<media:content url="http://gabrielegenta.files.wordpress.com/2011/04/cascade-data-store.png" medium="image">
			<media:title type="html">Cascade Data Store</media:title>
		</media:content>
	</item>
		<item>
		<title>Calliope &#8211; New Screenshots</title>
		<link>http://gabrielegenta.wordpress.com/2011/04/18/calliope-pr0-screenshots/</link>
		<comments>http://gabrielegenta.wordpress.com/2011/04/18/calliope-pr0-screenshots/#comments</comments>
		<pubDate>Mon, 18 Apr 2011 21:02:05 +0000</pubDate>
		<dc:creator>Gabriele Genta</dc:creator>
				<category><![CDATA[Calliope]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[preview]]></category>
		<category><![CDATA[screenshots]]></category>
		<category><![CDATA[Sproutcore]]></category>

		<guid isPermaLink="false">http://gabrielegenta.wordpress.com/?p=219</guid>
		<description><![CDATA[Today I fixed a couple subtle bugs in Calliope core, and I am one step closer to releasing the first preview. To celebrate I&#8217;m going to publish some screenshots of the main interface in action, and a todo list of &#8230; <a href="http://gabrielegenta.wordpress.com/2011/04/18/calliope-pr0-screenshots/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=219&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Today I fixed a couple subtle bugs in Calliope core, and I am one step closer to releasing the first preview. To celebrate I&#8217;m going to publish some screenshots of the main interface in action, and a <a title="Calliope – Preview 1 ToDo" href="http://gabrielegenta.wordpress.com/2011/04/21/calliope-pr1-todo/">todo list</a> of what is missing before the first preview/demo, hoping that will help keeping me on track.</p>
<p>Here comes the first screenshot:</p>
<p style="text-align:center;"><a href="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image1.png"><img class="aligncenter size-full wp-image-220" title="Calliope Preview: First Shot" src="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image1.png?w=584&#038;h=379" alt="" width="584" height="379" /></a></p>
<p>You can already notice a couple differences here from <a title="Introducing Calliope" href="http://gabrielegenta.wordpress.com/2011/03/18/introducing-calliope/" target="_blank">the first screenshot</a>:</p>
<ul>
<li>Buttons are labelled in English;</li>
<li>The graphics of the letters has changed slightly;</li>
<li>Rack has been redesigned too, and own letters have been highlighted in dark gray.</li>
</ul>
<p>There are also some new elements: first of all there is a simple label on the top of the screen, indicating what the turn number is and what the current player is; there is also a green frame surrounding the word &#8220;preview&#8221;. That, as you can easily guess, means that the word is correct.</p>
<p>Now, if I move the letter &#8220;S&#8221; from my rack up into the board&#8230;</p>
<p><span id="more-219"></span><a href="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image2.png"><img class="aligncenter size-full wp-image-221" title="Calliope Preview: moving a letter" src="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image2.png?w=584&#038;h=379" alt="" width="584" height="379" /></a>&#8230;the letter fades a little, and a blue marker appears, showing where the letter will be placed on release of the mouse button. Say I want to put the word &#8220;song&#8221; in place using the trailing &#8220;g&#8221; of &#8220;preparing&#8221; and the letters on my rack; after placing &#8220;so&#8221;, the board would look like this:</p>
<p><a href="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image3.png"><img class="aligncenter size-full wp-image-222" title="Calliope Preview: wrong word" src="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image3.png?w=584&#038;h=379" alt="" width="584" height="379" /></a></p>
<p>You got it right: a red highlight means the word is wrong. Placing the &#8220;N&#8221; in the right spot fixes it:</p>
<p><a href="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image4.png"><img class="aligncenter size-full wp-image-223" title="Calliope Preview: &quot;song&quot; complete" src="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image4.png?w=584&#038;h=379" alt="" width="584" height="379" /></a></p>
<p>But you are not playing alone. Suppose now to hit the &#8220;End Turn&#8221; button on the top right corner of the screen. Here is what happens:</p>
<ol>
<li>The control passes to your opponent (or the next player, if playing in more than two);</li>
<li>Your black letters on the board turn white, becoming part of it;</li>
<li>You are locked out of the board: you cannot drag letters on it;</li>
<li>You begin to see your opponent actions happening on the board, like you were doing them yourself.</li>
</ol>
<p>After a little dragging and dropping, here is what your opponent come up with:</p>
<p><a href="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image5.png"><img class="aligncenter size-full wp-image-224" title="Calliope Preview: opponent moves" src="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image5.png?w=584&#038;h=379" alt="" width="584" height="379" /></a>Notice here that your opponent&#8217;s letters are painted with a different shade of gray, so that you can distinguish them from your own and from what&#8217;s was already on the board at the beginning of the turn.</p>
<p>The image above was the last of the series, did you like them? <strong>Leave a comment!</strong></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gabrielegenta.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gabrielegenta.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gabrielegenta.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gabrielegenta.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gabrielegenta.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gabrielegenta.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gabrielegenta.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gabrielegenta.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gabrielegenta.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gabrielegenta.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gabrielegenta.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gabrielegenta.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gabrielegenta.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gabrielegenta.wordpress.com/219/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=219&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gabrielegenta.wordpress.com/2011/04/18/calliope-pr0-screenshots/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:thumbnail url="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image1.png?w=150" />
		<media:content url="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image1.png?w=150" medium="image">
			<media:title type="html">Calliope Preview: first shot</media:title>
		</media:content>

		<media:content url="http://0.gravatar.com/avatar/ada143e6c93581ebcbcf510187c13908?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielegenta</media:title>
		</media:content>

		<media:content url="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image1.png" medium="image">
			<media:title type="html">Calliope Preview: First Shot</media:title>
		</media:content>

		<media:content url="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image2.png" medium="image">
			<media:title type="html">Calliope Preview: moving a letter</media:title>
		</media:content>

		<media:content url="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image3.png" medium="image">
			<media:title type="html">Calliope Preview: wrong word</media:title>
		</media:content>

		<media:content url="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image4.png" medium="image">
			<media:title type="html">Calliope Preview: &#34;song&#34; complete</media:title>
		</media:content>

		<media:content url="http://gabrielegenta.files.wordpress.com/2011/04/pr0_image5.png" medium="image">
			<media:title type="html">Calliope Preview: opponent moves</media:title>
		</media:content>
	</item>
		<item>
		<title>Building Calliope &#8211; Sproutcore data sources (Part I)</title>
		<link>http://gabrielegenta.wordpress.com/2011/04/17/calliope-data-sources-p1/</link>
		<comments>http://gabrielegenta.wordpress.com/2011/04/17/calliope-data-sources-p1/#comments</comments>
		<pubDate>Sun, 17 Apr 2011 18:00:36 +0000</pubDate>
		<dc:creator>Gabriele Genta</dc:creator>
				<category><![CDATA[Calliope]]></category>
		<category><![CDATA[data-sources]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[restful]]></category>
		<category><![CDATA[Sproutcore]]></category>

		<guid isPermaLink="false">http://gabrielegenta.wordpress.com/?p=197</guid>
		<description><![CDATA[If you don’t know what Calliope is, please read this other post before continuing on. In this post I&#8217;m covering the problems I encountered while implementing data access in the client-side of Calliope using Sproutcore data sources. If you are starting now &#8230; <a href="http://gabrielegenta.wordpress.com/2011/04/17/calliope-data-sources-p1/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=197&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>If you don’t know what Calliope is, please read <a title="Introducing Calliope" href="http://gabrielegenta.wordpress.com/2011/03/18/introducing-calliope/" target="_blank">this other post</a> before continuing on.</p>
<p>In this post I&#8217;m covering the problems I encountered while implementing data access in the client-side of Calliope using Sproutcore data sources. If you are starting now to have a look at Sproutcore way of handling data, I suggest you have a look at these pages in the official documentation:</p>
<ul>
<li><a title="Sproutcore official guide about records" href="http://guides.sproutcore.com/records.html" target="_blank">Guide about records</a></li>
<li><a title="Sproutcore official guide about using data sources" href="http://guides.sproutcore.com/connect_server.html" target="_blank">Guide about using data sources</a></li>
<li><a title="Sproutcore wiki page about data stores" href="http://wiki.sproutcore.com/w/page/12412883/DataStore-Introduction" target="_blank">Wiki page about data stores</a> (a little older, but contains more details about certain subjects)</li>
</ul>
<p>The official documentation is well written, but it uses very simplistic examples that fall short in real word applications (even a simple one like Calliope) and it is missing the &#8220;big picture&#8221; of how things work. These, I think, are the main reasons why I &#8211; and I am not the only one &#8211; had such a hard time figuring out how to use the data store effectively.</p>
<p>With this post I hope to fill some of the gaps of the official documentation, by showing what problems I faced and how I resolved them.</p>
<p><span id="more-197"></span></p>
<p>For Calliope I have defined 5 Sproutcore models:</p>
<ul>
<li>Player</li>
<li>Game</li>
<li>Turn</li>
<li>TurnLetter</li>
<li>Action</li>
</ul>
<p>Since definitions are really simple I won&#8217;t paste them here, for a general description of the fields involved have a look at the <a title="Building Calliope – Data Model" href="http://gabrielegenta.wordpress.com/2011/03/26/calliope-data-model/" target="_blank">data model post</a>.</p>
<p>I think at the models as they were divided into two kinds: globals and locals. I put <em>Player</em> and <em>Game</em> into the &#8220;globals&#8221; definition, since they are located at the root level &#8211; that is, they have no parent model. For games this is not really precise: if you read the post about the design of services you could object that games are children of players; this is essentially true, but since a player can only see his/her games I will threat them as global entities.</p>
<p><em>Turn</em>, <em>TurnLetter</em> and <em>Action</em> are instead viewed as local entities, with a game as the parent.</p>
<p>This logical differentiation between global and local entities is represented in the program in the structure of the data sources: I coded a first data source to feed the data store with global data, and a second one &#8211; cascaded to the first &#8211; to handle local data related to a specified game. In the following I am going to cover the design of both data sources and how they are used to support the execution of the game.</p>
<h2>Global data source</h2>
<p>The global data source is implemented in a very simple way. There is essentially one local query defined for each global entity; those queries are defined as follows:</p>
<pre>Calliope.Player.ALL_PLAYERS = SC.Query.local(Calliope.Player);
Calliope.Game.ALL_GAMES = SC.Query.local(Calliope.Game);</pre>
<p>These queries are used to retrieve the whole list of players and games from the server, by issuing a find on the data store, like this:</p>
<pre>Calliope.store.find(Calliope.Player.ALL_PLAYERS);</pre>
<p>When this call is done for the first time in the life of the application, Sproutcore automatically calls the method <em>fetch</em> of the data source associated with the store (the global data source), passing in the query. That method essentially does a check on the query: if it matches one of the two defined above it calls the remote service for games (or players), saving the result into the store. The code related to the players is:</p>
<pre class="brush: jscript;">
Calliope.DataSource = SC.DataSource.extend({
  fetch: function(store, query) {
    if (Calliope.Player.ALL_PLAYERS === query) {
      Calliope.session.createRequest({
        address: &quot;/players&quot;
      }).notify(this, this._didFetchAllPlayers, query, store)
      .send();
    }
    return YES;
  }

  _didFetchAllPlayers: function(response, query, store) {
    var body = undefined;
    if (SC.ok(response)) {
      body = response.get(&quot;body&quot;);
    }
    if (SC.ok(response) &amp;&amp; SC.ok(body)) {
      // load the players into the store
      store.loadRecords(Calliope.Player, body);
      // notify store that we handled the fetch
      store.dataSourceDidFetchQuery(query);
    } else {
      // handle error case
      store.dataSourceDidErrorQuery(query, response);
    }
  }
});
</pre>
<p>Games case is handled in a very similar way.</p>
<p>So, the call to <em>find</em> loads in the store all the records of players and games. After doing that, issuing a find to the store using a record type and id let us retrieve instantly the record we are looking for. Here is a simple example (assuming that player &#8220;foo&#8221; has id 1):</p>
<pre>var playerFoo = Calliope.store.find(Calliope.Player, 1);</pre>
<p>And this is about everything you have to know about my usage of global stores: the calls to <em>find</em> on the queries of player and games are performed as long as the user logs in, and then the retrieved data is used throughout the rest of the application.</p>
<p><strong>End of Part I</strong></p>
<p>If you read this far please take the time to leave a comment to let me know what you liked, what you didn’t, and what you would do differently. Thank you.</p>
<p style="text-align:right;"><a title="Building Calliope – Sproutcore data sources (Part II)" href="http://gabrielegenta.wordpress.com/2011/04/27/calliope-data-sources-p2/">Go to Part II »</a></p>
<p><a title="Building Calliope – Index" href="http://gabrielegenta.wordpress.com/2011/03/21/building-calliope-index/">« Go back to the index</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gabrielegenta.wordpress.com/197/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gabrielegenta.wordpress.com/197/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gabrielegenta.wordpress.com/197/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gabrielegenta.wordpress.com/197/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gabrielegenta.wordpress.com/197/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gabrielegenta.wordpress.com/197/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gabrielegenta.wordpress.com/197/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gabrielegenta.wordpress.com/197/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gabrielegenta.wordpress.com/197/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gabrielegenta.wordpress.com/197/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gabrielegenta.wordpress.com/197/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gabrielegenta.wordpress.com/197/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gabrielegenta.wordpress.com/197/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gabrielegenta.wordpress.com/197/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=197&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gabrielegenta.wordpress.com/2011/04/17/calliope-data-sources-p1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ada143e6c93581ebcbcf510187c13908?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielegenta</media:title>
		</media:content>
	</item>
		<item>
		<title>Building Calliope &#8211; Services Design</title>
		<link>http://gabrielegenta.wordpress.com/2011/04/11/calliope-services-design/</link>
		<comments>http://gabrielegenta.wordpress.com/2011/04/11/calliope-services-design/#comments</comments>
		<pubDate>Mon, 11 Apr 2011 14:33:26 +0000</pubDate>
		<dc:creator>Gabriele Genta</dc:creator>
				<category><![CDATA[Calliope]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[restful]]></category>
		<category><![CDATA[symfony2]]></category>

		<guid isPermaLink="false">http://gabrielegenta.wordpress.com/?p=168</guid>
		<description><![CDATA[If you don’t know what Calliope is, please read this other post before continuing on. In this post I&#8217;m going to describe how the web services forming the backend of Calliope have been designed and built. I didn&#8217;t concentrate much on &#8230; <a href="http://gabrielegenta.wordpress.com/2011/04/11/calliope-services-design/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=168&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>If you don’t know what Calliope is, please read <a title="Introducing Calliope" href="http://gabrielegenta.wordpress.com/2011/03/18/introducing-calliope/" target="_blank">this other post</a> before continuing on.</p>
<p>In this post I&#8217;m going to describe how the web services forming the backend of Calliope have been designed and built. I didn&#8217;t concentrate much on designing them because I was eager to reach a visual result, so I know they&#8217;re not the best possible; I&#8217;m open to criticism and I hope with your help to improve the design.</p>
<p><span id="more-168"></span></p>
<h2>Introduction</h2>
<p>At the time I was beginning to develop Calliope I didn&#8217;t even know what RESTful was meaning, but there was quite a big hype around the word, so I decided to do some reading and figure out if that was the way to go. The book I chose for my research was <a title="RESTful Web Services on Amazon.com" href="http://www.amazon.com/RESTful-Web-Services-ebook/dp/B0043D2ED6/ref=sr_1_1?ie=UTF8&amp;m=A3KSZ402CI2EG1&amp;s=digital-text&amp;qid=1302520780&amp;sr=1-1">RESTful Web Services</a> by Richardson and Ruby (Kindle Edition of course).</p>
<p>After the reading it was clear that RESTful services where the right choice for my kind of application, mainly because of the promised lightness, which is well suited to reduce bandwidth occupation and, as a consequence, response time.<br />
After a little thinking I also decided that a good format for the services would be JSON: JSON is well understood by JavaScript and PHP, is lightweight and expressive enough for almost anything. JSON has no built-in way to connect services together (like writing links in XHTML), but this shouldn&#8217;t be a problem for my application.<br />
Last but not least, I decided to build my services as completely stateless in order to exploit all the advantages that statelessness brings with it.</p>
<p>To summarize, here are my choices:</p>
<ul>
<li>be RESTful;</li>
<li>use JSON as the format;</li>
<li>be stateless.</li>
</ul>
<h2>The Services</h2>
<p>RESTful services means thinking at your system as a bunch of resources, deciding one (or more) URI for each resource, and deciding how to represent it. With reference to <a title="Building Calliope – Data Model" href="http://gabrielegenta.wordpress.com/2011/03/26/calliope-data-model/">the data model</a> I described earlier, the main resources I can identify in Calliope are:</p>
<ul>
<li>players;</li>
<li>games;</li>
<li>turns;</li>
<li>letters;</li>
<li>actions.</li>
</ul>
<p>Every player can have a number of open games, every game is made of turns and actions. Actions can be linked either only to a game or to a game and specific turn; letters are linked to turns in order to implement the snapshot feature. As an additional information, not everyone can see every game: one can only see the games he or she is taking (or has taken) part in.<br />
Every resource is identified in the data model by a numeric id; that id is the natural choice for addressing the resource through an URI but, as we will see later &#8211; is not always the best one.</p>
<p><strong>Players</strong></p>
<p>Let&#8217;s talk about players first. Players are the simplest resource of the group, and I decided to model the service as follows:</p>
<pre>GET    /players                  retrieve list of players
POST   /players                  create a new player

GET    /players/{name}           retrieve info on player {name}
PUT    /players/{name}           edit info of player {name}
DELETE /players/{name}           delete player {name} 

GET    /players/{name}/avatar    retrieve avatar of player {name}
PUT    /players/{name}/avatar    edit avatar of player {name}
DELETE /players/{name}/avatar    delete avatar of player {name}</pre>
<p>Explanation for this is quite obvious: by issuing a GET on /players one can retrieve the complete list of players registered to the game (right now there is no restriction, in the future the results could be restricted to only the &#8220;friends&#8221; of the current user, or such). Here is an example of the response in JSON format:</p>
<pre>[
  {
    "name":"barfoo",
    "displayName":"Foo",
    "playerId":2
  },
  {
    "name":"foobar",
    "displayName":"Bar",
    "playerId":1
  }
]</pre>
<p>Once you have the list you can then retrieve detailed information on a certain player (say its username is &#8220;foobar&#8221;) by building an URI with the second rule above (in the example: /players/foobar). The response will look like a single object of the list response, with additional information (maybe about the user&#8217;s profile, or game stats) added to it; at the current stage of development a request of a single player produces exactly the same object as the list request.<br />
Anyway, by having the player username, you can also retrieve its avatar. Retrieving it is as simple as issuing a GET on /players/foobar/avatar. As a representation of the avatar an image is returned, it can be in one of the common formats of the internet, and could also be in a specific size.</p>
<p>In the previous paragraphs I only described the read part of services; there is also a write part, involving the other http methods:</p>
<ul>
<li>issuing a POST on /players let you creating a new player (&#8220;posting&#8221; a new player);</li>
<li>issuing a PUT or a DELETE on /players/foobar (or on the avatar) let you respectively edit or delete the specified item.</li>
</ul>
<p>In order to make one&#8217;s own stuff at hand, I decided to alias the resource /players/{my_username} with the simpler /me. Methods allowed, formats and semantics remain the same as stated above.</p>
<p><strong>Games</strong></p>
<p>Since there is no such thing as a &#8220;public&#8221; game, I decided to put all the games stuff under the /me resource, as such:</p>
<pre>GET    /me/games                 retrieve list of my games
POST   /me/games                 create a new game
GET    /me/games/{id}            retrieve info on game {id} 
PUT    /me/games/{id}            edit info of game {id}</pre>
<p>These services are similar to the one for players, except for the fact that the DELETE method is not supported, and that the numeric id is used for games whilst the username was used for players. I decided not to allow the deletion of games but only the hiding/archiving of them (action, this, that can be performed through a PUT on the game).</p>
<p>The representation of the game is quite simple, here is an example:</p>
<pre>{
  "time":"2011-03-11 21:56:44",
  "ended":false,
  "gameId":10,
  "turnCount":19,
  "players": [ 1, 2 ]
}</pre>
<p>As you can see there is the game creation time, a flag stating whether the game has ended or not, the id of the game (which is meaningful only when retrieving a list of games), the number of turns (which come in handy later) and an ordered array of player ids taking part into the game.</p>
<p><strong>Turns and Letters</strong></p>
<p>Turns and letters are closely linked, and since generally there is no reason one would need a single letter I decided to threat them together, so that letters are retrieved along when you ask for a specified turn. Moreover, I thought that the best way to address a turn inside a game is by its natural order number (first turn is turn 1, secondi is turn 2 and so on). This makes for a natural, compact and simple notation. Here are the routes (assume that * is replaced by /me/games/{id}):</p>
<pre>GET    */turns            retrieve list of turns of the game
POST   */turns            create a new turn
GET    */turns/{#}        retrieve info and letters for turn {#}</pre>
<p>A turn is viewed as a static snapshot of the game state and as such, once created, is immutable. For such reason neither PUT nor DELETE methods are allowed on it.<br />
When retrieving the list of turns only a brief information is returned about each turn, for example:</p>
<pre>{
  "time":"2011-03-11 21:56:44",
  "ended":false,
  "player":1,
  "turnNumber":1
}</pre>
<p>This doesn&#8217;t add much to the information given by retrieving the game itself, anyway this method is present for coherence with the others. What is instead interesting is that by retrieving a single turn one also receives the complete list of the letters forming the game snapshot at the beginning of the retrieved turn. Letters are retrieved in a &#8220;compressed&#8221; form, in order to occupy the less space possible, here is an example:</p>
<pre>{
  "time":"2011-03-11 21:56:44",
  "ended":false,
  "player":1,
  "turnNumber":1,
  "letters": [
    { "id":10369, "lid":1, "l":"A", "c":"s" },
    { "id":10370, "lid":2, "l":"A", "c":"s" },
    ...
  ]
}</pre>
<p>Where:</p>
<ul>
<li><strong>id</strong> is the letter data model identifier;</li>
<li><strong>lid</strong> is the letter id in the current game;</li>
<li><strong>l</strong> is the letter string;</li>
<li><strong>c</strong> is the letter container (<strong>b</strong> for board, <strong>r</strong> for rack, <strong>s</strong> for sack).</li>
</ul>
<p>In order to create a new turn issuing a POST on */turns one has to provide the full snapshot of the game in the form of letters and their position, in the same format as the one described above. You can of course start a new turn only if you&#8217;re playing in the current one.</p>
<p><strong>Actions</strong></p>
<p>As I said above, actions can be linked to a game alone (and is the case of chat messages), or to a game and a specified turn. In order to account for the two possibilities I defined these 4 routes (as before, assume that * is replaced by /me/games/{id}):</p>
<pre>GET    */actions            retrieve list of actions of the game
POST   */actions            add a new action to the game
GET    */turns/{#}/actions  retrieve list of actions of the turn {#}
POST   */turns/{#}/actions  add a new action to the turn {#}</pre>
<p>So, POSTing to */actions means creating a &#8220;global&#8221; game action, as opposed to POSTing to */turns/{#}/actions, which means posting a new action relative to the specified turn only.</p>
<p>By common sense and coherence with the other routes, GETting */actions should return only global actions, whilst GETting */turns/{#}/actions should return only local actions. But this choice is not ideal when seeing the game as an ordered stream of actions (this kind of view was introduced in the data model article, and is essential to the reconstruction of game state through actions). In order to effectively support this kind of view of the game I decided to make local turn actions also available via the &#8220;global&#8221; */actions. In such a way, when one issues a GET on */actions, the response will contain not only the global actions of the game, but also the local actions linked to a turn.<br />
Moreover, since the number of actions can become quite large, there is a need for filtering and selection of the results. As of now, I defined these additional parameters for */actions:</p>
<ul>
<li><strong>afterAction={actionId}</strong> &#8211; tells the service to return only actions with an id larger that the one specified in {actionId}, this is useful during online actions re-execution, in order to receive only the new actions (remember that the services are stateless, and so there is no way for the server to know which actions are already been received by the client);</li>
<li><strong>pivotOnly</strong> &#8211; tells the service to retrieve only pivotal actions, in order to speedup the re-execution of a large set of actions;</li>
<li><strong>turn={turnNumber}</strong> &#8211; tells the service to retrieve only those actions belonging to the specified turn.</li>
</ul>
<p>A typical call sequence for this service &#8211; which is the core of the whole application &#8211; looks like:</p>
<ol>
<li>GET */actions?turn={lastTurn}&amp;pivotOnly</li>
<li>GET */actions?afterAction={lastSeenAction1}</li>
<li>GET */actions?afterAction={lastSeenAction2}</li>
<li>&#8230;</li>
</ol>
<p>Where {lastTurn} is the number of the last turn of the game, as received getting information on the game itself; {lastSeenAction1} and {lastSeenAction2} are the ids of the last action received by the client respectively after call 1 and after call 2.</p>
<p>The representation of a single action looks like this:</p>
<pre>{
  "type":"letter_drag_end",
  "attributes":"{ ... }",
  "time":"2011-04-08 09:05:00",
  "t":"1302246300040",
  "actionId":24456,
  "pivot":true,
  "player":1
}</pre>
<p>As you can see this provides for the <em>actionId</em>, that can be used to set the value of the parameter <em>afterAction</em>.</p>
<h2>Reference</h2>
<p>Here is the complete list of the designed services. The ones in italic are yet to be implemented, whilst the others are more or less stable.</p>
<pre><strong>GET /players</strong>                  retrieve list of players
<em>POST /players create a new player</em>

<strong>GET /players/{name}</strong>           retrieve info on player {name}
<em>PUT /players/{name} edit info of player {name}</em>
<em>DELETE /players/{name} delete player {name} </em>
<strong>GET /players/{name}/avatar</strong>    retrieve avatar of player {name}
<em>PUT /players/{name}/avatar edit avatar of player {name}</em>
<em>DELETE /players/{name}/avatar delete avatar of player {name}</em>

<strong>GET /me/games</strong>                 retrieve list of my games
<strong>POST /me/games</strong>                create a new game
<strong>GET /me/games/{id}</strong>            retrieve info on game {id} 
<em>PUT /me/games/{id} edit info of game {id}</em></pre>
<p>and with * = /me/games/{id}:</p>
<pre><strong>GET */turns</strong>               retrieve list of turns of the game
<strong>POST */turns</strong>              create a new turn
<strong>GET */turns/{#}</strong>           retrieve info and letters for turn {#}

<strong>GET */actions</strong>             retrieve list of actions of the game
<strong>POST */actions</strong>            add a new action to the game
<strong>GET */turns/{#}/actions</strong>   retrieve list of actions of the turn {#}
<strong>POST */turns/{#}/actions</strong>  add a new action to the turn {#}</pre>
<h2>Last Note</h2>
<p>If you read this far please take the time to comment on this one, to let me know what you liked of the design, what you didn&#8217;t, and what you would do differently. Thank you.</p>
<p><a title="Building Calliope – Index" href="http://gabrielegenta.wordpress.com/2011/03/21/building-calliope-index/">« Go back to the index</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gabrielegenta.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gabrielegenta.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gabrielegenta.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gabrielegenta.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gabrielegenta.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gabrielegenta.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gabrielegenta.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gabrielegenta.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gabrielegenta.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gabrielegenta.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gabrielegenta.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gabrielegenta.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gabrielegenta.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gabrielegenta.wordpress.com/168/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=168&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gabrielegenta.wordpress.com/2011/04/11/calliope-services-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ada143e6c93581ebcbcf510187c13908?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielegenta</media:title>
		</media:content>
	</item>
		<item>
		<title>RaphaelWrapper demo and sample code</title>
		<link>http://gabrielegenta.wordpress.com/2011/03/30/raphaelwrapper-demo/</link>
		<comments>http://gabrielegenta.wordpress.com/2011/03/30/raphaelwrapper-demo/#comments</comments>
		<pubDate>Wed, 30 Mar 2011 11:37:19 +0000</pubDate>
		<dc:creator>Gabriele Genta</dc:creator>
				<category><![CDATA[RaphaelWrapper]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[Raphael]]></category>
		<category><![CDATA[Sproutcore]]></category>

		<guid isPermaLink="false">http://gabrielegenta.wordpress.com/?p=154</guid>
		<description><![CDATA[As promised, I published a small online demo application that uses RaphaelWrapper (if you do not know what I&#8217;m talking about, read this other post). Click here to see the demo The code of the demo is open source and &#8230; <a href="http://gabrielegenta.wordpress.com/2011/03/30/raphaelwrapper-demo/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=154&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>As promised, I published a small online demo application that uses RaphaelWrapper (if you do not know what I&#8217;m talking about, read <a title="RaphaelWrapper has gone Open Source" href="http://gabrielegenta.wordpress.com/2011/03/27/raphaelwrapper-opensource/" target="_blank">this other post</a>).</p>
<p><a href="http://gabrielegenta.files.wordpress.com/2011/03/raphaelwrapper_showcase.png"><img class="aligncenter size-full wp-image-161" title="RaphaelWrapper showcase" src="http://gabrielegenta.files.wordpress.com/2011/03/raphaelwrapper_showcase.png?w=584&#038;h=373" alt="" width="584" height="373" /></a></p>
<p style="text-align:center;"><strong><a title="RaphaelWrapper Showcase" href="http://www.playcalliope.com/raphael_wrapper/showcase" target="_blank">Click here to see the demo</a></strong></p>
<p>The code of the demo is open source and you can find it on github at <a title="RaphaelWrapper showcase repository" href="https://github.com/demerzel3/RaphaelWrapperShowcase">this address</a>, you can use it as a brief sample code for the library while I put up something more detailed.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gabrielegenta.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gabrielegenta.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gabrielegenta.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gabrielegenta.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gabrielegenta.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gabrielegenta.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gabrielegenta.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gabrielegenta.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gabrielegenta.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gabrielegenta.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gabrielegenta.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gabrielegenta.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gabrielegenta.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gabrielegenta.wordpress.com/154/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=154&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gabrielegenta.wordpress.com/2011/03/30/raphaelwrapper-demo/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ada143e6c93581ebcbcf510187c13908?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielegenta</media:title>
		</media:content>

		<media:content url="http://gabrielegenta.files.wordpress.com/2011/03/raphaelwrapper_showcase.png" medium="image">
			<media:title type="html">RaphaelWrapper showcase</media:title>
		</media:content>
	</item>
		<item>
		<title>RaphaelWrapper has gone Open Source</title>
		<link>http://gabrielegenta.wordpress.com/2011/03/27/raphaelwrapper-opensource/</link>
		<comments>http://gabrielegenta.wordpress.com/2011/03/27/raphaelwrapper-opensource/#comments</comments>
		<pubDate>Sun, 27 Mar 2011 11:40:39 +0000</pubDate>
		<dc:creator>Gabriele Genta</dc:creator>
				<category><![CDATA[Calliope]]></category>
		<category><![CDATA[RaphaelWrapper]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[Raphael]]></category>
		<category><![CDATA[Sproutcore]]></category>

		<guid isPermaLink="false">http://gabrielegenta.wordpress.com/?p=151</guid>
		<description><![CDATA[Today I decided to publish the source of my Sproutcore-Raphael integration framework &#8211; called RaphaelWrapper &#8211; so that others can exploit it and hopefully help me extend it. I posted it on github, you can find it here: https://github.com/demerzel3/RaphaelWrapper. RaphaelWrapper basically &#8230; <a href="http://gabrielegenta.wordpress.com/2011/03/27/raphaelwrapper-opensource/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=151&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Today I decided to publish the source of my Sproutcore-Raphael integration framework &#8211; called RaphaelWrapper &#8211; so that others can exploit it and hopefully help me extend it. I posted it on github, you can find it here: <a title="RaphaelWrapper on github" href="https://github.com/demerzel3/RaphaelWrapper">https://github.com/demerzel3/RaphaelWrapper</a>.</p>
<p>RaphaelWrapper basically gives access to Raphael functions through a Sproutcore-friendly view called CanvasView. I&#8217;m using this framework as the basis for my bigger project Calliope, but since it is a completely independent component of the application I thought it could have been useful to make it public.</p>
<p>In the next days I will publish an usage example, and hopefully a little online demo as well.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gabrielegenta.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gabrielegenta.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gabrielegenta.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gabrielegenta.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gabrielegenta.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gabrielegenta.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gabrielegenta.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gabrielegenta.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gabrielegenta.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gabrielegenta.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gabrielegenta.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gabrielegenta.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gabrielegenta.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gabrielegenta.wordpress.com/151/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=151&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gabrielegenta.wordpress.com/2011/03/27/raphaelwrapper-opensource/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ada143e6c93581ebcbcf510187c13908?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielegenta</media:title>
		</media:content>
	</item>
		<item>
		<title>Building Calliope &#8211; Data Model</title>
		<link>http://gabrielegenta.wordpress.com/2011/03/26/calliope-data-model/</link>
		<comments>http://gabrielegenta.wordpress.com/2011/03/26/calliope-data-model/#comments</comments>
		<pubDate>Sat, 26 Mar 2011 20:38:21 +0000</pubDate>
		<dc:creator>Gabriele Genta</dc:creator>
				<category><![CDATA[Calliope]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[real-time]]></category>

		<guid isPermaLink="false">http://gabrielegenta.wordpress.com/?p=56</guid>
		<description><![CDATA[If you don&#8217;t know what Calliope is, please read this other post before continuing on. Understanding the game The first step I took in building the data model for Calliope was trying to figure out how a game was structured, &#8230; <a href="http://gabrielegenta.wordpress.com/2011/03/26/calliope-data-model/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=56&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>If you don&#8217;t know what Calliope is, please read <a title="Introducing Calliope" href="http://gabrielegenta.wordpress.com/2011/03/18/introducing-calliope/" target="_blank">this other post</a> before continuing on.</p>
<p><span style="font-size:20px;font-weight:bold;">Understanding the game</span></p>
<p>The first step I took in building the data model for Calliope was trying to figure out how a game was structured, keeping in mind that a game is meant to be played in real time by different persons on different machines, and that the whole state of the game must be persisted in order for a player to be able to shut the game and go back to it anytime.</p>
<p>Obviously there are two or more players taking part in a game, and the game itself can be split into turns in which players interact. But what are the building blocks of a turn? During a turn a player can pick letters from the sack to put them on his/her rack, move letters around (between his/her rack and the board), chat with the opponents, and pass the turn. Each of these steps must be recorded by the system in the current player&#8217;s machine, in order to be reproducible on the other connected machines. I decided to threat the above steps all in the same way and to call them actions.</p>
<p><span id="more-56"></span></p>
<p>A fundamentally right choice would have been to forget the turns separation, and to model a game just by a single stream of actions. By following and re-executing the actions from start to end, the current game state could have always been reconstructed. Performance-wise anyway, that would have been an error. Imagine a very long game, build up of several turns: that would mean tons of actions (thousands, maybe), tons of actions to reproduce in order to be able to reconstruct the game&#8217;s state. In the scenario we are considering this is not acceptable.</p>
<p>In order to avoid an eccessive accumulation of actions I decided to introduce in the model the ability to take snapshots of the game&#8217;s state along the way, to allow for a snappier state reconstruction (that is, the state itself can be persisted at a given time, so that only the actions taken after the snapshot must be re-executed to reach the current game state). I thought that the best way to model the game&#8217;s state was by means of the letters involved: every game is played using 128 letter tiles; at the beginning all letters are in the sack and from then on &#8211; after each action of the game &#8211; they move:</p>
<ul>
<li>on the board, in a specific position (which can be modelled as a 2D point);</li>
<li>on someone&#8217;s rack.</li>
</ul>
<p>By saving the position of every letter in the game I can take an exact snapshot of the game&#8217;s state. From this point of view even actions can be rethought: every action &#8211; except from chat messages and turn passing, which are threatened apart &#8211; can be thought of as a movement of a letter from one location to another (from sack to rack, from rack to board, etc.).</p>
<p>Now that I have a way to represent snapshots I just have to decide when to take them. I decided to go for the simplest solution, and to take one snapshot per turn.</p>
<h3>To summarize:</h3>
<p>A <strong>game</strong> is split into <strong>turn</strong>s and played by two or more <strong>player</strong>s; every turn is associated with a snapshot &#8211; which contains the position of <strong>letter</strong>s at the beginning of the turn itself &#8211; and a set of <strong>action</strong>s &#8211; which tell what happened in the turn after the initial snapshot. To reconstruct the current game&#8217;s state one has to:</p>
<ol>
<li>fetch the last turn;</li>
<li>read the snapshot and position letters accordingly;</li>
<li>read the actions and re-execute them.</li>
</ol>
<p>In a similar way, one can &#8220;travel&#8221; through the game starting from the first turn and reconstruct every single step that was taken.</p>
<h2>The data model</h2>
<p>After the game structure has been made clear, it was time to translate it to database tables. Here is an E/R showing the model:</p>
<p><a href="http://gabrielegenta.files.wordpress.com/2011/03/model.png"><img class="aligncenter size-full wp-image-57" title="Calliope Data Model" src="http://gabrielegenta.files.wordpress.com/2011/03/model.png?w=584&#038;h=501" alt="" width="584" height="501" /></a></p>
<p>The <strong>game</strong> entity is linked may-to-many to the players by a middle entity called <strong>game_player</strong>, which add the information of the play order (and other less important stuff). The relation between <strong>turn_letter</strong> and <strong>turn</strong> implements the snapshot feature seen in the description above: every turn has 128 associated turn_letters, specifying the location (attribute <em>container</em>) and ownership (attribute <em>player_id</em>) of every letter in the game, effectively saving the state of the game at the beginning of the turn.</p>
<p>The <strong>action</strong> entity has a reference to the <strong>turn</strong> it was executed in, as expected, and is also linked directly to the <strong>game</strong>.<br />
The additional reference to the game has been added to account for what I call game-wide actions, that is: actions that are executed by a player during a game but are not related to any turn in particular. Chat messages are an example of game-wide actions.<br />
In order to account  for the maximum possible flexibility, an action has been modelled using a <em>type</em> &#8211; that can be any string describing the kind of action &#8211; and an <em>attributes</em> field. The attributes field is a CLOB, in which the system can store additional information necessary for the re-execution of the action, in whatever format (at current state attributes are stored as JSON).<br />
There is another additional field in action: the <em>pivot</em> flag. The pivot flag has been added in order to identify those actions that must absolutely be re-executed in order to properly reconstruct the game state; the identification of pivotal actions adds a little awareness to the system that can be useful in certain situations (e.g. if a game is reloaded while a turn was in progress a large set of actions must be re-executed, to boost performance the system can discard all non-pivotal actions and execute only relevant ones).</p>
<p>Just to give you a more concrete view on this stuff, here are the type of actions that I&#8217;ve defined:</p>
<ul>
<li><em>&#8220;message&#8221;</em> &#8211; a chat message, attributes contains just the string that was typed;</li>
<li><em>&#8220;letter_drag_*&#8221;</em> &#8211; letter drag related actions; there&#8217;s an action type for the beginning of the drag, one for the movement of the letter while dragging, one for successful drop and one for unsuccessfull drop; attributes contains the identifier of the letter that was dragged, its initial location (before the drag) and the current one;</li>
<li><em>&#8220;turn_end&#8221;</em> &#8211; issued when a player passes his/her turn, there&#8217;s always an action of this kind at the end of every turn.</li>
</ul>
<p><a title="Building Calliope – Index" href="http://gabrielegenta.wordpress.com/2011/03/21/building-calliope-index/">&laquo; Go back to the index</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gabrielegenta.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gabrielegenta.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gabrielegenta.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gabrielegenta.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gabrielegenta.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gabrielegenta.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gabrielegenta.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gabrielegenta.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gabrielegenta.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gabrielegenta.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gabrielegenta.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gabrielegenta.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gabrielegenta.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gabrielegenta.wordpress.com/56/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gabrielegenta.wordpress.com&amp;blog=11051243&amp;post=56&amp;subd=gabrielegenta&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gabrielegenta.wordpress.com/2011/03/26/calliope-data-model/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ada143e6c93581ebcbcf510187c13908?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gabrielegenta</media:title>
		</media:content>

		<media:content url="http://gabrielegenta.files.wordpress.com/2011/03/model.png" medium="image">
			<media:title type="html">Calliope Data Model</media:title>
		</media:content>
	</item>
	</channel>
</rss>
