<?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"
	>

<channel>
	<title>For Great Justice</title>
	<atom:link href="http://greatjustice.info/feed/" rel="self" type="application/rss+xml" />
	<link>http://greatjustice.info</link>
	<description>Great justice is great.</description>
	<pubDate>Sat, 22 Nov 2008 19:40:26 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Using Bitmasks in a Groups Permission System</title>
		<link>http://greatjustice.info/using-bitmasks-in-a-groups-permission-system/</link>
		<comments>http://greatjustice.info/using-bitmasks-in-a-groups-permission-system/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 18:00:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[bitmasks]]></category>

		<guid isPermaLink="false">http://greatjustice.info/?p=38</guid>
		<description><![CDATA[As promised in my previous post, this article will describe a practical application of bitmasks, in this particular case for usage in a permission system on a webapplication. This particular application is a social network site, in which a user can create a joinable group. Each group has four usergroups - Guests, Members, Moderators, and [...]]]></description>
			<content:encoded><![CDATA[<p>As promised in <a title="The Lost Art of Bitmasks at GreatJustice.info" href="http://greatjustice.info/the-lost-art-of-bitmasks/" target="_blank">my previous post</a>, this article will describe a practical application of bitmasks, in this particular case for usage in a permission system on a webapplication. This particular application is a social network site, in which a user can create a joinable group. Each group has four usergroups - Guests, Members, Moderators, and Administrators, and as a special group with no specific traits of its own, Creator(s) (i.e. the person(s) that created the group).</p>
<p>Each usergroup has a set of permissions in each group - so basically, you have to be able to store a usergroup&#8217;s permissions on a per-group basis. In this article, I&#8217;ll explain how I&#8217;ve used bitmasks and the associated operators as explained in the previous article to store those permissions, as well as the usergroup(s) a particular user belongs to in a specifc group. The bottom line is that by storing the permission a usergroup has in a bitmask, you end up with a lot less database usage. But that&#8217;ll be explained in this article.</p>
<p><span id="more-38"></span>First though, a case study. This is actually a good idea for pretty much every software application, both as a whole and its parts - analyze what you&#8217;re trying to do. In this case, I wanted to create a social network site of sorts (using the <a title="The Zend Framework on GreatJustice.info" href="http://greatjustice.info/zend-framework/" target="_blank">Zend Framework</a>) with, next to the obvious user profiles and user-to-user communication, a &#8216;groups&#8217; system, where users can create groups, clubs, or whatnot, each with its own discussions (or &#8216;threads&#8217;, you could basically also see it as a forum where users can create their own sections). More specifically, the owner / Administrator of a Group should be able to determine the access people have to their own groups - for example, a private group, an invite-only group, a read-only group, etcetera.</p>
<p>To implement this, a permission system would have to be setup. I was already pretty sure I&#8217;d use a default set of usergroups (Creators, Administrators, Moderators, Members and groupless, Guests), also called Roles, which more properly describes the per-group Role a User has - in group A, a User may just be a visiting Guest, whilst in group B the user would be a Moderator, and in C a Member, etc.</p>
<p>Next to that, I also figured that one User may fulfill more than one Role - in first instance the Creator / Administrator combination, where a Creator in its own doesn&#8217;t have any particular rights or duties, but when combined with the Administrator role, a Creator rises above the &#8216;regular&#8217; Administrator rank, in that he cannot be removed from the group by other Administrators. In retrospect, allowing every user to have more than one Role at a time might&#8217;ve been a little overkill, but it&#8217;s quite manageable in terms of the database storage required to associate a User with a Group.</p>
<p>In the database, there&#8217;s a link table, GroupUsers, that contains the group ID, the user ID, and the Role, the latter being a regular integer value. Just one column to indicate the user&#8217;s Role, no matter how many Roles the user has.</p>
<p>Next to assigning Roles to Users on a per-group basis, a Role would also need to have a set of Permissions, also on a per-group basis. In other words, in one group a Member could, for example, create new threads, whilst in another a Member could only reply to threads, all based on the choice of the Administrator(s) of that particular group.</p>
<p>So another requirement was that per Group, the permissions of a Role would have to be stored.</p>
<p>The Permissions are basically a list of sorts, containing items such as</p>
<p>(users with this Role can:)</p>
<ul>
<li>View the group</li>
<li>View threads</li>
<li>Edit threads</li>
<li>Create new threads</li>
<li>Reply to threads</li>
<li>Edit own posts</li>
<li>Edit other people&#8217;s posts</li>
<li>etc</li>
</ul>
<p>The permissions each Role has can be determined and set with the above list of permissions. Next to that, it&#8217;s relatively easy to extend these permissions.</p>
<p>The problem however is storage. In a regular system, one might say that the Role has a list of boolean permission values in that Group - canViewGroup, canViewThreads, canEditThreads, etcetera. Translating that to a database schema is also easy - just add boolean columns canViewGroup, canViewThreads, etcetera, with values 0 or 1 in them.</p>
<p>However, this makes the Groups table, in which we can store the permissions for each group, needlessly long - for each role + permission, a column is needed, so with just the above 7 permissions, 28 columns would be needed to store these. One of the base rules of database design is to make your database tables as narrow as possible - as few columns as possible. The narrower the table, the less data has to be processed and searched through, the faster access is.</p>
<p>In order to solve this particular problem, <a title="The Lost Art of Bitmasks at GreatJustice.info" href="http://greatjustice.info/the-lost-art-of-bitmasks/" target="_blank">bitmasks</a> were used. Instead of storing each permission as its own boolean value, each permission has its own unique mask - as described in the previous article. The permissions itself is stored in a numerical value, both in the program&#8217;s code itself (the Group object) and in the database. Instead of having the amount of roles times the amount of permissions in database columns for each Group, you can now do with just one column per usergroup. Here&#8217;s how it&#8217;s done. We keep everything in the Group object, since that&#8217;s where the Roles&#8217;  Permissions are stored. You could opt to put the storage of Roles in a separate object, but it makes no functional or logical difference (there&#8217;s a 1-to-1 relationship between a Group and its permissions).</p>
<p>In the Group object, we put the numerical values that store the permissions for each usergroup, and we define a list of constants that represent the bitmasks (or &#8216;flags&#8217;) for each permission. Note again that all permissions are powers of 2, as explained in the <a title="The Lost Art of Bitmasks on GreatJustice.info" href="http://greatjustice.info/the-lost-art-of-bitmasks/" target="_blank">other article</a>. Note also the usage of class-level constants, introduced in PHP 5 (I believe).</p>
<pre name="code" class="php">class Group
{
	const PERM_VIEW_GROUP = 1;
	const PERM_VIEW_THREADS = 2;
	const PERM_EDIT_THREADS = 4;
	const PERM_CREATE_THREADS = 8;
	const PERM_REPLY_THREADS = 16;
	const PERM_EDIT_OWN_POSTS = 32;
	const PERM_EDIT_OTHER_POSTS = 64;

	private $administratorPermissions = 0;
	private $moderatorPermissions = 0;
	private $memberPermissions = 0;
	private $guestPermissions = 0;

}</pre>
<p>For each Role, methods can be defined that set, unset, add or remove permissions to a certain usergroup. </p>
<p> </p>
<pre name="code" class="php"	// sets the Administrator role's permissions to the given value.<br />
	public function setAdministratorPermissions($perms)
	{
		$this-&gt;administratorPermissions = $perms;
	}

	// returns the Administrator role's permissions
	public function getAdministratorPermissions()
	{
		return $this-&gt;administratorPermissions;
	}

	// Adds a permission to the Administrator role.
	public function addAdministratorPermission($perm)
	{
		// we use the |= operator, which is equal to $value = $value | $perm
		$this-&gt;administratorPermissions |= $perm;
	}

	// Removes / unsets the given permission from the Administrator role's permissions.
	public function removeAdministratorPermission($perm)
	{
		$this-&gt;administratorPermissions &amp;= ~$perm
	}

	// checks if the Administrator role has the given permission
	public function getAdministratorPermission($perm)
	{
		return (($this-&gt;administratorPermissions &amp; $perm) != 0);
	}</pre>
<p>Rinse and repeat for the other usergroups. Of course, all this could be condensed into even smaller chunks. You could also, to further redue the storage used for permission, create additional permission masks, the full set for each usergroup - i.e. MODERATOR_PERM_CAN_VIEW_THREAD, etc. However, you'll probably run up against the limitations of the system - i.e. that a number can only contain so much bits before it overflows. If you have only a few permissions, you could chuck it all into a single value, but if you have more (more than 8), use separate variables.</p>
]]></content:encoded>
			<wfw:commentRss>http://greatjustice.info/using-bitmasks-in-a-groups-permission-system/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Lost Art of Bitmasks</title>
		<link>http://greatjustice.info/the-lost-art-of-bitmasks/</link>
		<comments>http://greatjustice.info/the-lost-art-of-bitmasks/#comments</comments>
		<pubDate>Tue, 30 Sep 2008 18:00:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[bitmasks]]></category>

		<guid isPermaLink="false">http://greatjustice.info/?p=37</guid>
		<description><![CDATA[In this article, I will attempt to explain the so-called bitmasks, and the application of the binary operators (such as &#38;, &#124;, &#60;&#60; and &#62;&#62;) found in pretty much every programming language. I myself have been in my education for four years now, but only last year or so did I encounter a practical application [...]]]></description>
			<content:encoded><![CDATA[<p>In this article, I will attempt to explain the so-called bitmasks, and the application of the binary operators (such as <code>&amp;</code>, <code>|</code>, <code>&lt;&lt;</code> and<code> &gt;&gt;</code>) found in pretty much every programming language. I myself have been in my education for four years now, but only last year or so did I encounter a practical application for using them. The title is as such perhaps just personal, seeing that I don&#8217;t really know the level of most modern-day programmers or whether they&#8217;re familiar with binary operations, but in my own experience, more emphasis is put on high-level structures and techniques, compared to low-level data storage, management and manipulation. This article will provide an introduction to binary operators, as well as how and when they can be applied - in a basic fashion, I&#8217;m sure that a lot more advanced applications for these techniques can be thought up.</p>
<p><span id="more-37"></span></p>
<p>I&#8217;m fairly sure that every beginning programmer will read through the introductionary text of a new programming language and encounter several operators whose function remains unknown - I&#8217;m referring to the <code>&amp;</code>, <code>|</code>, <code>&lt;&lt;</code> and <code>&gt;&gt;</code> operators, which are present in pretty much every programming language. These operators are the binary <code>AND</code>, binary <code>OR</code>, and the left and right bitshift operators. Some will research further and, if they&#8217;re familiar with binary numbers (i.e. how numbers are represented in a processor, on the lowest level, with ones and zeroes), might also discover what it is they do exactly on a value.</p>
<p>However, a practical application for those doesn&#8217;t always make itself apparent. For me personally, it took three years (or four, dunno exactly) before I finally encountered an application for it. This was whilst I was working on Clan Arena / <a title="C4 engine on GreatJustice.info" href="http://greatjustice.info/the-c4-engine/" target="_blank">the C4 engine</a>, whose code contains a relatively large amount of binary operators and functionality.</p>
<p>In C4, the application of these operators is numerous, but it often boils down to one thing - setting and reading properties of an object, for example a renderable 3D model. One property of a model was how it was rendered - render its wireframe, textures, shadow, specific shadow mode, and I dunno what else. Those are just examples btw, I&#8217;m not actually sure how they were really used.</p>
<p>The point with that particular application was that you could assign several settings to a model, whilst internally, each setting was stored in just a single, numerical variable. This means that you could set a number of &#8216;flags&#8217;, as they&#8217;re also referred to, to a single object.</p>
<p>The easiest comparison is with booleans. Pretty much everyone knows the boolean true / false logic, so that shouldn&#8217;t need any more explanation. Let&#8217;s say you&#8217;re writing a 3D engine and you&#8217;re at the part where to decide which part of a model to render - wireframe, texture, shadow, etc. A model, in this case, can indicate what it wants the engine to render, i.e. the model has a set of properties - let&#8217;s call em <code>renderWireframe</code>, <code>renderTexture</code>, and <code>renderShadow</code>, all boolean variables.</p>
<p>For each rendering pass, the engine will check these three variables and render accordingly. Simple enough.</p>
<p>Now, with bitmasks and binary operators, you could store these three (and many more, up to 32 or 64) variables into just one single variable, an integer. This is a prime example of data encapsulation in OOP environments - from the outside, the renderable object has a few methods, say, <code>getRenderShadow()</code>, <code>getRenderWireframe()</code>, and <code>getRenderTexture()</code>, but on the inside, these three booleans are all stored into a single variable.</p>
<p>The easiest way to picture this is to rotate the three booleans to a horizontal orientation. Let&#8217;s say the number <code>1</code> is the boolean true, and <code>0</code> is the boolean false (which, btw, is perfectly applicable to C/C++ and other languages in that order). You&#8217;d get some vars like:</p>
<pre name="code" class="cpp">bool renderWireframe = 0;
bool renderTexture = 1;
bool renderShadow = 1;</pre>
<p>In this example, we want to render the model&#8217;s texture and shadow, but not the wireframe. When you take the values, rotate them horizontally, you&#8217;d get the following value:</p>
<pre>011</pre>
<p>A binary number which, if you happen to know binary, can also be interpreted as the number 3, thus reducing the amount of variables used to store the rendering information from 3 to 1. You may think that this isn&#8217;t a major improvement, but imagine you have to send the rendering variables through a <code>Message</code>, as I&#8217;ve described in <a title="Applied Design Patterns: C4 Messages" href="http://greatjustice.info/applied-design-patterns-c4-engine-messages/" target="_blank">an earlier post</a>: Next to the <code>Model </code>object&#8217;s three variables, you&#8217;d also get a <code>Message </code>object with the same three variables.</p>
<p>In the default C4 implementation, this&#8217;ll take a few minutes to create. When you reduce the amount of variables in the <code>Model</code> to 1, you also get a <code>Message</code> with just 1 variable to send - which takes less time to write , and reduces the overhead of packing / unpacking the message by a factor 3 at most (probably a lot less, seeing that the original booleans took up just 3 bits in memory, compared to the 32 or 64 bits an integer would take up). Multiply this saving by the amount of times the message is sent back and forth, and you&#8217;ll notice a major improvement (logically speaking, that is, it&#8217;ll probably save amounts that can only be measured in nanoseconds, something you&#8217;ll hardly notice)</p>
<p>This particular example is probably easy to imagine, but can easily be converted to the inner workings of a program itself - Objects send each other messages all the time, in the form of method invocations and the passing of other Objects. Reduce the amount of variables, and you get less method invocations, less memory access overhead, etcetera.</p>
<p>In a follow-up article, I&#8217;ll explain how I&#8217;ve used this technique for an access control system for a PHP-based website / application. For now though, I&#8217;ll try to explain how to use the system described above.</p>
<h2>Usage</h2>
<p>There&#8217;s basically three operations you&#8217;ll need to know in order to work with binary variables / bitmasks: Reading, writing, and deleting / unsetting. Reading involves checking a variable if it&#8217;s got a certain value - in the above example, for example, you&#8217;ll want to check whether to render textures or not, and in a later stage, whether to render shadows or not. Writing is also important, since you&#8217;ll have to set the value at some point. Finally, unsetting involves removing a value from the variable.</p>
<p>We&#8217;ll start by setting a flag / bitmask in a variable.</p>
<p>First, you&#8217;ll have to declare a variable that contains the information. In this case, we&#8217;ll use C/C++ datatypes, but this technique applies to pretty much every programming language. We&#8217;ll initialize it to 0.</p>
<pre name="code" class="cpp">int var = 0;</pre>
<p>Note that the binary representation of this number is <code>00000000</code> in an 8-bit system (we&#8217;ll use just 4 bits for this example purpose, in a modern-day system this&#8217;ll probably be 16, 32, 64 or even 128 bits).</p>
<p>Second, we&#8217;ll have to have a base value for all possible settings that can be set. As in, we&#8217;ll want to declare a few constant values that represent the settings. These constants, and this is important, have to be a power of 2, like 1, 2, 4, 8, 16, 32, 64, 128, etcetera. If you translate those to binary, you get sequences like <code>0001</code>, <code>0010</code>, <code>0100 </code>and <code>1000 </code>- note that each binary number has just one 1 set, the rest is 0. We&#8217;ll define the constants as such:</p>
<pre name="code" class="cpp">const int renderWireframe = 1;
const int renderTexture = 2;
const int renderShadow = 4;</pre>
<p>In C/C++ and most other languages, you can simplify this action by using the bitshift operator (<code>&lt;&lt;</code>). This will basically move all 1&#8217;s in a binary number one space to the left, so that <code>0001 &lt;&lt; 1</code> (bitshift <code>0001 </code>with 1 space) will result in <code>0010</code>, as shown in the example below. This however doesn&#8217;t work in all languages - PHP, for example, has problems with assigning the outcome of an operator to a constant. You can just use the notation above, the result is the same.</p>
<pre name="code" class="cpp">const int renderWireframe = 1 &lt;&lt; 0; // 1
const int renderTexture = 1 &lt;&lt; 1;   // 2
const int renderShadow = 1 &lt;&lt; 2;// 4</pre>
<p>In this case, you won&#8217;t have to manually calculate the power of 2 yourself, which, at least for higher numbers, is convenient - and you don&#8217;t want to risk miscalculations, not even with one number, since it&#8217;ll cause unexpected results.</p>
<p>I&#8217;ll explain the reasoning behind this in a bit, if you don&#8217;t get it by then. First though, we&#8217;ll write a value into our integer variable we declared earlier.</p>
<h3>Assignment</h3>
<p> To assign a value to a binary variable, you&#8217;ll need to use the binary OR operator - the single | character, like so:</p>
<pre name="code" class="cpp">var = var | renderTexture;</pre>
<p>(note that some languages also have the <code>|=</code> operator, which can also be used instead.) The <code>OR</code> operator basically says something like: &#8216;For each number in the binary representation of the resulting variable, set to 1 if either <code>var</code> or <code>renderTexture</code> also has a 1 at that position&#8217;. A calculus notation will clarify (I hope):</p>
<pre>0000
0010
---- |
0010

0 OR 0 = 0
0 OR 0 = 0
0 OR 1 = 1
0 OR 0 = 0</pre>
<p>(feel free to replace 0 and 1 with false and true, and the <code>|</code> operator with the <code>||</code> operator, which compares the variables on a true/false level, a step higher than the binary level)</p>
<p>We&#8217;ve added renderTexture to the var, indicating we&#8217;ll want to render the texture. Let&#8217;s also add the renderShadow one:</p>
<pre name="code" class="cpp">var = var | renderShadow;</pre>
<p>Which looks like</p>
<pre>0010
0100
---- |
0110

0 OR 0 = 0
0 OR 1 = 1
1 OR 0 = 1
0 OR 0 = 0</pre>
<p>Hopefully, the reasoning behind assigning only powers of 2 to the constants become clear now - assign anything but a power of 2, and you could get multiple flags set in the variable, which isn&#8217;t what you intend. Unless you do, of course.</p>
<p>Now, our variable called var has a value of <code>0110</code>, which, translated back to the decimal system, is 6. Note that 6 is neither the value of the <code>renderTexture</code> constant, nor the value of the <code>renderShadow</code> constant - it&#8217;s a combination of the two. It also isn&#8217;t a power of 2. Because of this, you can&#8217;t compare the value with one of the constants using the <code>==</code> operator directly - you&#8217;ll have to extract the value from the variable, or, to be more precise, check if the value you&#8217;re checking for is contained in the variable.</p>
<h3>Querying</h3>
<p>To do this, we use the binary <code>AND</code> operator, <code>&amp;</code>, on both the var and the constant, and check if the result is anything but 0. Let&#8217;s check if our variable has the <code>renderShadow</code> flag set. Note that <code>AND</code> works the same as <code>OR</code>, with the exception that the resulting binary number is only set to 1 if both the first AND the second binary number at the position is 1.</p>
<pre>0110
0100
---- &amp;
0100</pre>
<p><code>0100</code> is not 0, so we can safely say that the <code>renderShadow</code> flag is set inside the variable. I said earlier to see if the variable is simply &#8216;anything but 0&#8242;, but the above example indicates that the result is actually equal to the <code>renderShadow</code> constant - why not compare it with that? There&#8217;s a number of reasons for that, actually, the primary one being that it&#8217;s a lot simpler. What&#8217;s easier to type:</p>
<pre name="code" class="cpp">if ((var &amp; renderShadow) != 0)</pre>
<p>or</p>
<pre name="code" class="cpp">if ((var &amp; renderShadow) != renderShadow)</pre>
<p>?</p>
<p>The result is in both cases the same - true in this particular example - but the former is a lot easier to write. In fact, in a lot of languages that are either typeless or semi-loosely typed, in which a regular int can, for example, also be interpreted as a boolean, such as C/C++, you could also just do</p>
<pre name="code" class="cpp">if (var &amp; renderShadow)</pre>
<p>and leave out the comparison entirely - in C/C++ and PHP (haven&#8217;t tried this in other languages yet), anything but 0 is interpreted as a boolean true, when used in an if-statement.</p>
<p>However, it&#8217;s considered bad practice to use it in this way, since it may cause confusion and doesn&#8217;t work this way in all languages. Not only that, but it confuses one type with another - whilst an integer can be interpreted and used as a boolean, they&#8217;re logically speaking two entirely different things. I made a mistake when I tried to put the result of one of these operations into a variable - instead of the result (a boolean true or false), the variable was set to the numerical value of the result (4 in the above example), producing odd, unexpected results.</p>
<h3>Querying multiple masks</h3>
<p>You should note however that you can only check for one value at a time using this method (using the comparison to 0), even though you&#8217;ve learned how to combine two binary values with each other earlier using the <code>OR</code> operator. The reason is that, when comparing a variable <code>AND</code>-ed with a combination of two values, the resulting value will be a non-0 value even when just one of the two flags is set. This can be prevented by comparing the resulting variable with the combination value instead of checking if it&#8217;s not 0 . An example:</p>
<pre name="code" class="cpp">var = 0;
var = var | renderTexture; // set var to 0010

// check if var is set to both renderTexture and renderShadow
if ((var &amp; (renderTexture | renderShadow) != 0)
</pre>
<p>First we combine the two constants:</p>
<pre>
0010 // renderTexture
0100 // renderShadow
---- |
0110
</pre>
<p>Then we do the comparison:</p>
<pre>
0110 // renderTexture | renderShadow
0010 // var
---- &amp;
0010</pre>
<p><code>0010</code> is 2, is not 0, so the comparison would return true - even though <code>renderShadow</code> wasn&#8217;t set. Compare it with the combination of the two instead of &#8216;higher than 0&#8242;, and you&#8217;ll get the right result:</p>
<pre name="code" class="cpp">if ((0010 &amp; 0110) == (renderTexture | renderShadow))
</pre>
<pre>
0010 &amp; 0110 = 0010
0010 &amp; 0100 = 0110
</pre>
<p>Or, in full</p>
<pre name="code" class="cpp">
if ((var &amp; (renderTexture | renderShadow)) == (renderTexture | renderShadow))
</pre>
<p><code>0010</code> is not equal to <code>0110</code>, so the above comparison returns false, which is what we expected. You&#8217;ll have to do some more typing to get this to work though, and do the or-ing of the two constants twice (unless you place the or-ed version in a local variable or, if you do the combined comparison a lot, a constant on its own).</p>
<pre name="code" class="cpp">int cmp = (renderTexture | renderShadow);
if ((var &amp; cmp) == cmp) {}</pre>
<h3>Unsetting</h3>
<p>The third and final operation we&#8217;ll want to be able to perform, is to unset a flag from the variable. To do this, we AND the variable with the <em>inverse </em>of the mask. Previously, we did the AND-operator, that turned 0100 and 0110 into 0100, since only the second 1 was set and both numbers have to be 1 in order to have a 1 in the same position in the result. To unset a variable however, we&#8217;ll want the inverse to happen - set the value to 0 if both numbers are 1, i.e. the position in the variable has to be set to 0 at the position where the flag is 1.</p>
<p>If we have a value 0110, and a mask 0100, and we want to unset the mask from the value (i.e. remove the second 1 in the value), we use the inverse of the mask and AND that with the value.</p>
<p>We take the mask 0100 and we inverse it, which can be done with the ~ operator in most languages (bitwise NOT). The inverse of 0100, ~0100, is 1011. ANDing that with the value 0110, and we get:</p>
<pre>0110
1011
---- &amp;
0010</pre>
<p>or the value minus the flag value.</p>
<p>(another use of the binary NOT operator is to get the maximum value an integer can have - simply echo ~0, the binary NOT of 0, and you get a binary value of all 1&#8217;s, or the maximum integer value)</p>
<p>That&#8217;s about all there is to binary operators. As I said in the beginning, I&#8217;ll attempt to describe an application of this technique with a real-world example, by using the bitmask technique to define roles for users, and permissions belonging to those roles. The major advantage of using bitmasks in such a manner is that of database storage - you only need one database column to describe everything a user having a role can do. But more on that in the follow-up.</p>
]]></content:encoded>
			<wfw:commentRss>http://greatjustice.info/the-lost-art-of-bitmasks/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Zend Framework</title>
		<link>http://greatjustice.info/zend-framework/</link>
		<comments>http://greatjustice.info/zend-framework/#comments</comments>
		<pubDate>Tue, 29 Jul 2008 11:24:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Frameworks]]></category>

		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://greatjustice.info/?p=36</guid>
		<description><![CDATA[There are numerous web application frameworks written in and for PHP on the market nowadays, most of them free and/or open source, most of them following or supporting the MVC paradigm. This summer, I&#8217;m going to go and attempt to make a website using one of the newer frameworks out there: the Zend Framework. Made [...]]]></description>
			<content:encoded><![CDATA[<p>There are numerous web application frameworks written in and for PHP on the market nowadays, most of them free and/or open source, most of them following or supporting the MVC paradigm. This summer, I&#8217;m going to go and attempt to make a website using one of the newer frameworks out there: the Zend Framework. Made (or at least started / supported by) the people / company that also does the PHP language itself, it promises a solid framework for web application development, &#8216;extreme simplicity and productivity&#8217; (from the <a title="Why Zend Framework? at framework.zend.com" href="http://framework.zend.com/whyzf/" target="_blank">website</a>), up-to-date with the latest internet technologies, etcetera.</p>
<p>In this post (and following posts), I will dive into Zend Framework, describe its various loosely-coupled components, and make an attempt at judging the framework.</p>
<p><span id="more-36"></span></p>
<p>For this summer vacation, I had decided to start my own website project, just to keep up-to-date and whatnot. Since PHP is the most supported scripting language (and currently supported by my relatively cheap host), I decided to do it in that - much less hassle trying to get it online. Although PHP isn&#8217;t my favorite language, I decided to give it another serious try, with everything I&#8217;ve learned of OO programming and design during the last few years.</p>
<p>Earlier, I&#8217;ve played around with Ruby on Rails, the web application framework that sparked an enormous flood in MVC frameworks in various programming languages - amongst which PHP. I even made a simple site with that, got some hosting for it (which was quite more expensive than my current host), and attempted to put it online&#8230; but that failed.</p>
<p>Later, I played around with CakePHP, a very popular PHP framework that, as other frameworks do as well, offers an MVC structure, an object-relational mapper, AJAX support, and all that and then some. I didn&#8217;t finish the website I started to built with it (due to uncertainties with the people that were going to use / run / operate it and my own lack of interest), so I am not able to properly judge CakePHP. I was annoyed by how you insert variables in templates though - when I attempted it, you had to echo an array index from an object field:</p>
<p>$something-&gt;post['Post'];</p>
<p>or something like that - I can&#8217;t remember. Looking at <a title="Cake Blog Tutorial" href="http://book.cakephp.org/view/326/the-cake-blog-tutorial" target="_blank">the current quickstart</a>,  they&#8217;ve changed it to echo-ing a structure like</p>
<p>$post['Post']['id'];</p>
<p>but that still isn&#8217;t to my liking - it&#8217;s an array in an array in an equally-named variable. If there are multiple posts, which is the only reason I can think of why you&#8217;d use a two-dimensional array, at least call your variable $posts (plural), and run through all the posts with a foreach loop or something.</p>
<p>Anyways, that was probably more than a year ago. So this summer, I finally decided to start working on my own website and, following some rumours on the internets about Zend Framework, I decided to give it a try.</p>
<p>The Zend Framework is in a lot of respects the same as all those other PHP frameworks out there, having a database abstraction layer, MVC support, AJAX support, and all that. The main thing that ZF stands out for however is that it&#8217;s all loosely-coupled - using one component of Zend Framework, for example the database layer, does not mean you also have to use their MVC component, and vice-versa. There&#8217;s a list of components of the Zend Framework in the <a title="Zend Framework documentation" href="http://framework.zend.com/manual/en/" target="_blank">programmer&#8217;s documentation</a>, and for the biggest part, they all work independently of each other. For example, if you want to configure your database connection (using <a title="Zend_Db" href="http://framework.zend.com/manual/en/zend.db.html" target="_blank">Zend_Db</a>), you can do that by passing an array of the configuration parameters, or you can use an instance of <a title="Zend_Config" href="http://framework.zend.com/manual/en/zend.config.html" target="_blank">Zend_Config</a>, which can also be initialized in multiple ways (by using an ini or XML file, or by passing a PHP array). These decouplings and lack of dependencies between Zend Framework components is one of the major points in the entire framework. It doesn&#8217;t force you to use one or the other. Want to use your own controller structure? No problem. Want to use a third-party database abstraction layer? No problem either.</p>
<p>Zend doesn&#8217;t force you to use anything, it leaves you with the choice. And I believe that is a very good philosophy.</p>
<p>So far, I&#8217;ve spent a good week or so on the framework, progressing through the development by reading the documentation on one component, then building part of my application using that, followed by reading up on another component, and intergrating that into my application. It&#8217;s relatively easy to remodel an existing application to use Zend Framework components, or to add additional functionality to your program. Which I find a nice way of working, since you can take learning the framework one step at a time, whenever you&#8217;re ready for it.</p>
<p>So far, I&#8217;ve only used a small part of the Zend Framework - Zend_Controller, Zend_Db, Zend_Form, Zend_Filter,  and Zend_Validator conciously. Some more components are used unconciously, such as Zend_View and whatnot, but it&#8217;s possible to replace those as well. As such, I&#8217;m nowhere near providing an accurate description or review of the framework. However, in the week or so I have noticed several things, both positive and negative.</p>
<p>First, there&#8217;s quite a lot and thorough description of each component in the Zend_Framework, which explain the biggest parts of each component. There&#8217;s also a complete API available, although the documentation on that isn&#8217;t very extensive - three-worded method descriptions and such, for example. With that, the documentation is just &#8216;good&#8217;, not perfect. But since the framework is still in development, with the 1.6 version being released as a release candidate not too long ago, I&#8217;m sure that&#8217;ll come along soon.</p>
<p>Next, there are serious demands for new framework components. They have to have an 80% test coverage, proper documentation, adhere to the coding standards, and so forth. The test coverage requirement is, in my perspective, especially valueable, since it gives some degree of guarantee that the framework is good in terms of quality. I haven&#8217;t actually seen the tests (or even executed them) yet, but I do plan on writing tests for my own application, once I have a basic version done.</p>
<p>However, not everything is fine and dandy with the Zend Framework. While it does offer a large set of components, it isn&#8217;t really intended to be a full website framework. For example, it isn&#8217;t shipped with an object-relational mapper (yet), or with scaffolding purposes, which, for other frameworks, are often used for advertising purposes (as in: lookie me! I can make a blog in 5 minutes!). This means that some components, such as object / relational communications have to be written by the developer himself. The Zend Framework makes the development of a website a lot easier, but doesn&#8217;t take all the work from the developer. This can be seen as both a good and a bad thing. It&#8217;s good because it allows a lot of freedom and control for developers, allowing them to control pretty much every aspect of their website, without relying on auto-generated code or underlying functionality. It&#8217;s bad however because it&#8217;s not very easy to learn for new users. The latter part can probably be solved by both extensive documentation (a full tutorial isn&#8217;t yet available) and frameworks built on top of the Zend Framework, that do add features such as scaffolding to the framework. Such features might be added to the framework itself in a future date.</p>
<p>All in all, I like Zend Framework. It doesn&#8217;t seem to be aimed entirely at new developers, isn&#8217;t pretentious or promising instant websites, but offers a professional framework for serious developers that know what they&#8217;re doing, without forcing their hand into using components that may not be applicable for their particular situation. I&#8217;m also unable to judge whether the Zend Framework is suitable for (relatively) new programmers either. I&#8217;m not having any serious learning problems with it, since I like to tell myself I know proper object-oriented programming, but I can imagine that new programmers will have problems with it, due to it giving a lot of freedom, requiring a lot of design knowledge, and the absence of step-by-step guides for building a full website.</p>
<p>In the near future, I&#8217;ll (probably) be writing some more articles concerning the Zend Framework and/or components therein.</p>
<p><strong>EDIT</strong>: My bad, the Zend Framework does have some sort of object/relational mapper, in the form of the Zend_Db_Table and Zend_Db_Table_Row classes, which represent a database table and/or table row. The latter one in specific is the OR-mapper, and allows you to call methods like save() to store a row into the database. I&#8217;ll try and write an article on it once I figure it out properly for myself and I cba.</p>
]]></content:encoded>
			<wfw:commentRss>http://greatjustice.info/zend-framework/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Applied design patterns: C4 Engine Messages</title>
		<link>http://greatjustice.info/applied-design-patterns-c4-engine-messages/</link>
		<comments>http://greatjustice.info/applied-design-patterns-c4-engine-messages/#comments</comments>
		<pubDate>Tue, 15 Jul 2008 15:00:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[C++]]></category>

		<category><![CDATA[Design Patterns]]></category>

		<category><![CDATA[C4]]></category>

		<category><![CDATA[Composite]]></category>

		<category><![CDATA[Factory Method]]></category>

		<category><![CDATA[Visitor]]></category>

		<guid isPermaLink="false">http://greatjustice.info/?p=34</guid>
		<description><![CDATA[In my previous article about the C4 engine, I highlighted what was, in my opinion, the biggest downside of the C4 engine: its demo game. Or more precisely, the code and design of the demo game. Because I had to get points for university and didn&#8217;t have time to dive into said code and refactor [...]]]></description>
			<content:encoded><![CDATA[<p>In <a title="C4 Engine article @ GreatJustice.info" href="http://greatjustice.info/the-c4-engine/" target="_blank">my previous article about the C4 engine</a>, I highlighted what was, in my opinion, the biggest downside of <a title="C4 engine website @ terathon.com" href="http://www.terathon.com/c4engine/index.php" target="_blank">the C4 engine</a>: its demo game. Or more precisely, the code and design of the demo game. Because I had to get points for university and didn&#8217;t have time to dive into said code and refactor it all, I wrote a refactoring proposal (found here: <a title="C4 Engine Demo refactoring proposal (.doc)" href="http://greatjustice.info/wp-content/refactoring-proposal.docx">Office &#8216;97-&#8217;03</a> / <a title="C4 Engine Demo Game refactoring proposal (.docx)" href="http://greatjustice.info/wp-content/refactoring-proposal.doc">Office &#8216;07</a>) and put it on the <a title="C4 engine forums" href="http://www.terathon.com/forums/index.php" target="_blank">C4 Engine forums</a>. After that, and after the project, I still had to get some points, so I executed some of the refactorings.</p>
<p>So far, most refactorings I&#8217;ve done involve moving functionality from one central Game class to different smaller classes - resource and game management so far. One refactoring however is one I&#8217;m pretty proud of (in all decency), and is described in the refactoring proposal as the Composite Message System.</p>
<p>In this article, I&#8217;ll (attemt to) explain the process of this particular refactoring: explain the old situation, what the problem was with that situation, how it was analyzed and how, eventually (and with the help of my trusty Design Patterns book) I came up with a replacement system of that situation, one that was a lot more flexible and reusable, and one that would accellerate the speed at which programmers could produce results.</p>
<p>For those that are interested, I&#8217;ll be discussing the Composite, Visitor, Factory Method and (to a lesser degree) Builder design patterns in this article.</p>
<p><span id="more-34"></span></p>
<h2>Ye Olde slash Current Situation</h2>
<p>While I&#8217;m not officially allowed to post any real code from the C4 engine or demo game, I&#8217;m pretty sure there&#8217;s no restrictions to discussing said code / design.</p>
<p>In the current situation, you can send messages to other clients through C4&#8217;s MessageMgr class, accessible through a global (shudder) variable, TheMessageMgr. The MessageMgr has a SendMessage method, which takes an address (in the form of the key of the recipient, managed by said MessageMgr) and a Message. This Message is a subclass of C4&#8217;s Message class, a class that contains some management functions (message ID number and such), but mainly defines the behavior of subclasses.</p>
<p>In a C4-made game, a subclass of Message has to be created for each message type. For example, say you want to send a chat message to a certain player. In C4, you&#8217;ll have to create a new class ChatMessage, which extends Message. ChatMessage would contain two variables: Sender, a long value referring to the player who sent the message, and Message, a String (or character array) containing the actual message.</p>
<p>C4&#8217;s Message interface defines that any Message should also implement a Compress() and a Decompress() method, two methods that basically pass a Compressor and/or a Decompressor object to the Message object, on which methods can be called so that the Message can add and extract its own data from a byte stream (or whatever, I don&#8217;t know / don&#8217;t need to know how the data is actually represented inside the Compressor / Decompressor objects). So you&#8217;ll have the following methods:</p>
<pre name="code" class="cpp">void ChatMessage::Compress(Compressor&amp; data)
{
	data &lt;&lt; sender;
	data &lt;&lt; message;
}

bool ChatMessage::Decompress(Decompressor&amp; data)
{
	data &gt;&gt; sender;
	data &gt;&gt; message;
}
</pre>
<p>Basically, the Compressor and Decompressor implement the &lt;&lt; and &gt;&gt; operators, which add and extract the data from their internal representation. This actually adheres to the <a title="Visitor pattern @ Wikipedia" href="http://en.wikipedia.org/wiki/Visitor_pattern" target="_blank">Visitor design pattern</a> already, where a client sends an object to another object, where this other object (a Message subclass in this case) calls methods on the visiting object to, in this case, add data to it.</p>
<p>So, in total, to create a new Message type, you have to create a new class (in a header file) containing the class itself, the fields, two constructors, accessors for the fields, and a Compress and Decompress method. Next, implement the methods defined in the header file in a .cpp file (as well as message sending and receiving functionality, but that&#8217;s something for another day.) Sounds straightforward enough, and to be honest, it is.</p>
<p>However.</p>
<p></p>
<p>Say you want to create  another message that sends an announcement to all players, say, a server message that appears in the middle of each player&#8217;s screen. Simple enough, create a new Message class that contains a string and done. Rinse and repeat the above operations of new files, new class, constructors, compress / decompress, accessors, and implementation. Next, you want to send a notification that playey X has left the game. Again, simple enough, just create a new message type PlayerLeftMessage, which contains just one long value (the player key), constructors, accessors, compress/decompress, implement&#8230; wait a minute, didn&#8217;t we do that earlier?</p>
<p>The observant reader will notice that in the above example, three full-on message types were created, each about 50 lines in total (no comments, with whitespace), and each containing roughly the same methods and functionality. The only actual difference between the three is the data they contain / send, and an internal key to uniquely identify the message type on reception. Not very much. And yet, you have to create a full class for it.</p>
<p>Let&#8217;s break it down a bit more. The types of data that can be sent over a network is limited by what the Compressor and Decompressor classes can handle in their &lt;&lt; and &gt;&gt; operators. These types include:</p>
<ul>
<li>Booleans</li>
<li>Floating point numbers</li>
<li>Chars / Unsigned chars</li>
<li>Character arrays (Strings)</li>
<li>Shorts / Unsigned shorts</li>
<li>Longs / Unsigned longs</li>
<li>Long64 / Ulong64 (64 bits integers)</li>
</ul>
<p>All messages, one way or the other, send these and only these values. More advanced data types, such as for example the Vector3D type, are broken down into components and sent. The Vector3D is broken down into 3 floating point numbers (floats), for example.</p>
<p>What does this mean? It means that, one way or the other, <em>every message is composed of the above data types</em>.  Every message type converts the data they have to send to these types. They all do, no exceptions.</p>
<h2>Solution</h2>
<p>As I came to realize this, I figured there had to be a better, more flexibe way to define new message types, using the components described above. I read the chapter in the Design Patterns book on the Composite design pattern (since all message types were &#8216;composed&#8217; of the above types), and attempted to work out a solution, as described in <a title="C4 demo game refactoring proposal" href="http://greatjustice.info/wp-content/refactoring-proposal.docx" target="_blank">the refactoring proposal document</a>.</p>
<p>The solution involved defining a class structure that allows a client to dynamically assemble (&#8217;compose&#8217;) a message type from both simple and complex &#8216;modules&#8217;, building blocks so to speak. There&#8217;s basically two types of building blocks: &#8216;Leaf&#8217;-blocks and &#8216;Composed&#8217; blocks. Leaf blocks are the lowest point in the imaginary Composite Message tree, and contain one type of data - corresponding to the above list of Compressor-supported data types. It contains just one field, and implements both the Compress and Decompress methods defined by C4&#8217;s Message class.</p>
<p>The Composed block is a bit more advanced. It contains an internal list of other blocks (which can be either other Composed objects or leaves), and methods for traversing that list. It also implements the Compress and Decompress method, but instead of calling the Compressor / Decompressor&#8217;s &lt;&lt; and &gt;&gt; operators, it passes the Compressor / Decompressor objects on to its subnodes&#8217; own Compress / Decompress methods, so they can perform whatever action they need to do on it. If one of the subnodes is a leaf node, it&#8217;ll add or extract its own locally stored data to the Compressor / Decompressor object. If it&#8217;s another Composed node, it&#8217;ll pass the Compressor / Decompressor on to its children.</p>
<p>The figure below illustrates.</p>
<p><a href="http://greatjustice.info/wp-content/composite-message-diagram.gif"><img class="alignnone size-full wp-image-35" title="composite-message-diagram" src="http://greatjustice.info/wp-content/composite-message-diagram.gif" alt="Composite Message diagram" width="500" height="203" /></a></p>
<p>In this diagram, SomeMessage and Vector3DMessage are Composed Messages, while StringMessage, LongMessage and FloatMessage are leaf messages. All message nodes can be treated equally - they all, directly or indirectly, inherit from C4&#8217;s Message class. They all implement a Compress / Decompress method. They&#8217;re also all subclasses of a custom CompositeMessage type, which defines methods for traversing the tree.</p>
<p>To construct a CompositeMessage, which now is a means of defining a new Message type as described earlier, all a programmer has to do now is a handful of code statements:</p>
<pre name="code" class="cpp">
CompositeMessage * message = new ComposedMessage();
message-&gt;AddSubnode(new StringMessage("some string here"));
message-&gt;AddSubnode(new LongMessage(10));

TheMessageMgr-&gt;SendMessage(message);</pre>
<p>Three lines to create a new message type that would otherwise take 50. Quite an improvement, if I say so myself. Of course, there&#8217;s more to this than the above, as I realized after I had thought out this design.</p>
<p>You now have a tree of CompositeMessage objects, which are either ComposedMessage or LeafMessage types. Which one? No clue - as it should be. Proper OO programming involves not knowing or needing to know what specific implementation of a class you&#8217;re working with. So in the above example, you could see the entire tree as a tree of CompositeMessage objects.</p>
<h2>Extracting data</h2>
<p>However. How are you supposed to get the data stored in that from it now? This was the problem I had as well, and which I discussed with some people on the internets. From those, I gathered the Visitor design pattern is usually the means of traversing a tree and getting data from it.</p>
<p>Earlier in this article, we briefly passed this Visitor design pattern - the Compress and Decompress methods in the Message subclasses are both Visitor methods. The Compressor and Decompressor objects passed to those are Visitor objects. Such an approach could also be used in the Composite Message type.</p>
<p>In order to extract the data from a Composed message, I thought up a Visitor object that contained a list of sorts for each supported data type, as well as accessors for those. For each data type, there&#8217;s an AddXValue() and an GetXValue() method, that in turn adds a value of type X to the Visitor and get a value of type X from the Visitor. GetXValue will return the first X value when it&#8217;s called the first time, the second when called the second time, etcetera - according to a first in, first out pattern.</p>
<p>In the CompositeMessage type, a Visit method was added for each subclass to implement, which passes a Visitor object to the object. A Leaf subclass would implement it by calling Visitor-&gt;AddXValue(), passing its locally stored value to the Visitor. A Composed subclass would implement it by passing the Visitor to each of its subnodes.</p>
<p>Once the Visitor has traversed all the nodes of the Composite message, it&#8217;s filled with data, which can be extracted by the client again using the GetXValue() methods. An example:</p>
<pre name="code" class="cpp">
CompositeMessage * message = new ComposedMessage();
message-&gt;AddSubnode(new StringMessage("some string here"));
message-&gt;AddSubnode(new LongMessage(10));

Visitor * visitor = new Visitor();
message-&gt;Visit(visitor);
String * someString = message-&gt;GetStringValue();
long someLong = message-&gt;GetLongValue();
</pre>
<p>Looks straightforward enough. The only thing to keep in mind is that the data should be extracted in the order the composite message was assembled. This method can also be used to fill the CompositeMessage with data, by defining a FillVisit method for each CompositeMessage subclass. Instead of calling Visitor-&gt;SetXValue() however, the GetXValue() method is called and its resulting value is set as the object&#8217;s local data.</p>
<p>Speaking of assembling, it&#8217;s best if a CompositeMessage type is assembled from only one point in the program, so that the exact same structure is maintained each time the CompositeMessage is composed (or &#8216;built&#8217;). To accomplish this, we&#8217;ll use the Factory Method design pattern. For each Composite message type, we define a construction method that takes the initial values of the various components of the Composite Message. Here&#8217;s an example:</p>
<pre name="code" class="cpp">
CompositeMessage * CreateSomeMessage(Vector3D someVector, long someLong, float someFloat)
{
	CompositeMessage * message = new CompositeMessage();
	message-&gt;addSubnode(new Vector3DMessage(someVector));
	message-&gt;addSubnode(new LongMessage(someLong));
	message-&gt;addSubnode(new FloatMessage(someFloat));

	return message;
}
</pre>
<p>Simple and straightforward enough.</p>
<h2>Consequences</h2>
<p>This structure has both up- and downsides.</p>
<p>Using this structure makes it a lot easier to quickly create new message types. The process of new files, new class, fields, constructors, accessors, compress/decompress methods and all that is no longer needed, instead a programmer now assembles a message in three lines that earlier took 50, not counting documentation. Chucking it into a Factory Method as defined above adds some lines, but still nowhere near 50. This leads to increased production speed, and allows the programmer to concentrate on his task of solving problems, instead of the tedious business of writing the same class over and over again, with only slight differences.</p>
<p>Dynamic. With this structure, it&#8217;s possible to define message types at runtime, based on various factors. As such, the complexity of a message can be adjusted to the requirements. You could create a large, complex composite message for a player&#8217;s initial data, then adjust it to a much smaller / simpler one that only contains the data that has been updated.</p>
<p>Compatible with existing Message system. There&#8217;s no need whatsoever to change anything in the engine&#8217;s network code, since as far as the engine&#8217;s concerned, the CompositeMessage is just yet another Message. So this system can easily be used alongside existing messages, so that a transferrence from or to this system can be executed gradually, one message type at at time, without breaking the rest of the application.</p>
<p>There are however also some disadvantages to this system:</p>
<p>For one, it&#8217;s not as straightforward anymore. In the old system, all you had to do was call message-&gt;GetSender() (or something) to get the sender of a chat message. Now, you first have to create a Visitor object, pass it to the composite message, and call GetLongValue() from the Visitor. It&#8217;s a few extra steps, and it&#8217;s a lot more ambiguous - who says the long value received from the Visitor is really a player&#8217;s key? It&#8217;s uncertain, which means that in order to use this system, you have to keep track of the message type, and the order of data.</p>
<p>Also, it&#8217;s slower than the existing. The existing method was just a class with some message. Sending a new message involved creating a new instance of this class, and done. Creating a new CompositeMessage instance involves creating an X-amount of new objects, depending on the amount of data to be sent, and calling several methods on said objects before it can be sent. And that&#8217;s not all, for when it&#8217;s received again, the entire tree has to be traversed twice - once by the Decompressor object to fill it with data, and once again by the Visitor object to extract the data. How much slower this is, I don&#8217;t know - if in fact it is measureable - but it requires more instructions than the existing system. I&#8217;m guessing the performance decrease is negligible though, considering that at the same time messages are received and such, C4&#8217;s engine calculates loads of matrix transforms and whatnot.</p>
<p>Finally, this system can be used alongside the existing message system. Didn&#8217;t I already say that before? I did, since this point can be seen as both an advantage and a disadvantage. It&#8217;s in this case disadvantageous because the two message systems can become confused with each other - when one message is a class and another is a CompositeMessage, you&#8217;ll end up with maintaining two different systems. It&#8217;s best to do either one or the other, not both. But I guess that&#8217;s also personal.</p>
<p></p>
<h2>Code</h2>
<p>Anyway, for points I went and implemented the system (or a version thereof) explained in the refactoring proposal document. I&#8217;ll post the code below, but first, a warning: I haven&#8217;t properly tested this code. I did translate a few messages to the system, but nothing really complex, and nowhere enough to say this code is safe. If you&#8217;re planning on using this code, don&#8217;t assume it&#8217;ll work. I won&#8217;t give any guarantees.</p>
<p>Here&#8217;s the code. Hope you don&#8217;t mind the massive amount of code (relatively), and that Wordpress messed up the indentation.</p>
<p>CompositeMessage.h</p>
<pre name="code" class="cpp">
#ifndef CompositeMessage_h
#define CompositeMessage_h

#include "C4Messages.h"
#include "C4Engine.h"

namespace C4
{

/*
The Visitor class is a class representing an object that is able to traverse a
Complex Message structure to gather data.
*/
class Visitor
{
private:

// For each data types, two fields have to be defined:
// * The array (or whatever) used to store the data
// * A counter keeping track of the last data returned.

// Long values
Array longValues;
long currentLongValue;

Array unsignedLongValues;
long currentUnsignedLongValue;

// Boolean values
Array boolValues;
long currentBoolValue;

// Float values
Array floatValues;
long currentFloatValue;

// String values
Array stringValues;
long currentStringValue;

// Char values
Array charValues;
long currentCharValue;

Array unsignedCharValues;
long currentUnsignedCharValue;

// Short values
Array shortValues;
long currentShortValue;

Array unsignedShortValues;
long currentUnsignedShortValue;

// long64 values
Array long64Values;
long currentLong64Value;

Array
unsignedLong64Values;
long currentUnsignedLong64Value;

public:
Visitor();
~Visitor();

// Long values
void AddLongValue(long value);
long GetLongValue(void);

void AddUnsignedLongValue(unsigned long value);
unsigned long GetUnsignedLongValue(void);

// Bool values
void AddBoolValue(bool value);
bool GetBoolValue(void);

// Float values
void AddFloatValue(float value);
float GetFloatValue(void);

// String values
void AddStringValue(const char * value);
const char * GetStringValue(void);

// Char values
void AddCharValue(char value);
char GetCharValue(void);

void AddUnsignedCharValue(unsigned char value);
unsigned char GetUnsignedCharValue(void);

// Short values
void AddShortValue(short value);
short GetShortValue(void);

void AddUnsignedShortValue(unsigned short value);
unsigned short GetUnsignedShortValue(void);

// Long64 values
void AddLong64Value(long64 value);
long64 GetLong64Value(void);

void AddUnsignedLong64Value(ulong64 value);
ulong64 GetUnsignedLong64Value(void);
};

/*
The CompositeMessage class acts as the interface to all CompositeMessage subclasses,
and defines the basic behavior of all subclasses. The main two subclasses to this class
are LeafMessage and ComposedMessage - see those for more information.

*/
class CompositeMessage : public Message
{
public:
// Constructor, used to set an identifier for the Message.
// Passes type to the Message constructor.
CompositeMessage(MessageType type);
~CompositeMessage(void);

// The Compress method is called right before a Message is sent.
virtual void Compress(Compressor&amp; data) const;

// The Decompress method is called after the type of a Message has
// been determined.
virtual bool Decompress(Decompressor&amp; data);

// The Add method adds a subnode to a CompositeMessage.
virtual void Add(CompositeMessage * subnode);

// The Visit method should, when implemented by a leaf class,
// pass its data to the Visitor object. When implemented by a Composed
// class, it should pass the Visitor to its subnodes and, when appropriate,
// extract the data from the visitor, assemble its complex object, and
// pass that to the Visitor again.
virtual void Visit(Visitor * visitor) const;

// The FillVisit method works the same as the Visit method, except should
// be used to extract data from the Visitor and assign that data to the local
// fields. Once again, Composed message types should pass the Visitor on to
// subclasses.
virtual void FillVisit(Visitor * visitor);

// The GetData method is implemented by the CompositeMessage itself,
// and will create a Visitor object, send it through its own structure
// (regardless of whether it's a tree or just a single node), and return
// the filled Visitor to the calling client.
virtual Visitor * GetData(void) const;
};

/*
The LeafMessage class is the parent class to all Composite Message nodes
that do not have any subnodes of themselves. Therefore, the Add method
will remain unimplemented (i.e. will do nothing) for Leaf nodes.

Subclasses usually contain one basic type value, so you get
BoolMessage, LongMessage etc subclasses to this class.

Note that LeafMessage is an abstract class, and does not implement
any functions itself.
*/
class LeafMessage : public CompositeMessage
{
public:
LeafMessage(MessageType type);
~LeafMessage(void);

// Compresses the local data into a Compressor.
virtual void Compress(Compressor&amp; data) const;

// Extracts data from the Decompressor and stores it in a local value
virtual bool Decompress(Decompressor&amp; data);

// Stores locally stored data into the given Visitor object.
virtual void Visit(Visitor * visitor) const;

// Extracts data from the Visitor object and stores it locally.
virtual void FillVisit(Visitor * visitor);
};

/*
The ComposedMessage class is a class that can be used
to compose more comples messages. It implements the Add,
Compress, Decompress, Visit and FillVisit methods,
each of which will traverse the array of subnodes
also defined in this class.

Subclasses that implement these four classes should all,
at one point, call this class's implementations. This can
be done either before or after doing their own thing.
*/
class ComposedMessage : public CompositeMessage
{
private:
Array subnodes;
public:
ComposedMessage(MessageType type);
~ComposedMessage(void);

// Adds the passed CompositeMessage, which can either be a leaf or another ComposedMessage,
// to the list of subnodes.
void Add(CompositeMessage * subnode);

// Will iterate through all subnodes and pass the Compressor object to each
// subnode's Compress method.
void Compress(Compressor&amp; data) const;

// Will iterate through all subnodes and pass the Decompressor object to each
// subnode's Deompress method.
bool Decompress(Decompressor&amp; data);

// Will iterate through all subnodes and pass the Visitor object to each
// subnode's Visit method.
void Visit(Visitor * visitor) const;

// Will iterate through all subnodes and pass the Visitor object to each
// subnode's FillVisit method.
void FillVisit(Visitor * visitor);
};

/*
Leaf Message type used to store a boolean value.
*/
class BoolMessage : public LeafMessage
{
private:
bool value;
public:
BoolMessage(MessageType type, bool val = false);
BoolMessage(bool val = false);
~BoolMessage(void);
void Compress(Compressor&amp; data) const;
bool Decompress(Decompressor&amp; data);
void Visit(Visitor * visitor) const;
void FillVisit(Visitor* visitor);
};

/*
Leaf Message type used to store a long value.
*/
class LongMessage : public LeafMessage
{
private:
long value;
public:
LongMessage(long val = 0L);
LongMessage(MessageType type, long val = 0L);
~LongMessage(void);
void Compress(Compressor&amp; data) const;
bool Decompress(Decompressor&amp; data);
void Visit(Visitor * visitor) const;
void FillVisit(Visitor * visitor);
};

/*
Leaf Message type used to store an unsigned long value.
*/
class UnsignedLongMessage : public LeafMessage
{
private:
unsigned long value;
public:
UnsignedLongMessage(unsigned long val = 0L);
UnsignedLongMessage(MessageType type, unsigned long val);
~UnsignedLongMessage(void);
void Compress(Compressor&amp; data) const;
bool Decompress(Decompressor&amp; data);
void Visit(Visitor * visitor) const;
void FillVisit(Visitor * visitor);
};

/*
Leaf Message type used to store a long64 value. (see C4Types.h for long64 info)
*/
class Long64Message : public LeafMessage
{
private:
long64 value;
public:
Long64Message(long64 val = 0L);
Long64Message(MessageType type, long64 val = 0L);
~Long64Message(void);
void Compress(Compressor&amp; data) const;
bool Decompress(Decompressor&amp; data);
void Visit(Visitor * visitor) const;
void FillVisit(Visitor * visitor);
};

/*
Leaf Message type used to store an ulong64 (unsigned long64) value. (see C4Types.h for ulong64 info)
*/
class UnsignedLong64Message : public LeafMessage
{
private:
ulong64 value;
public:
UnsignedLong64Message(ulong64 val = 0L);
UnsignedLong64Message(MessageType type, ulong64 val = 0L);
~UnsignedLong64Message(void);
void Compress(Compressor&amp; data) const;
bool Decompress(Decompressor&amp; data);
void Visit(Visitor * visitor) const;
void FillVisit(Visitor * visitor);
};

/*
Leaf Message type used to store a char value.
*/
class CharMessage : public LeafMessage
{
private:
char value;
public:
CharMessage(char val = ' ');
CharMessage(MessageType type, char val);
~CharMessage(void);
void Compress(Compressor&amp; data) const;
bool Decompress(Decompressor&amp; data);
void Visit(Visitor * visitor) const;
void FillVisit(Visitor * visitor);
};

/*
Leaf Message type used to store an unsigned char value.
*/
class UnsignedCharMessage : public LeafMessage
{
private:
unsigned char value;
public:
UnsignedCharMessage(unsigned char val = ' ');
UnsignedCharMessage(MessageType type, unsigned char val = ' ');
~UnsignedCharMessage(void);
void Compress(Compressor&amp; data) const;
bool Decompress(Decompressor&amp; data);
void Visit(Visitor * visitor) const;
void FillVisit(Visitor * visitor);
};

/*
Leaf Message type used to store a string (or char pointer / array) value.
See also C4String.h.
*/
class StringMessage : public LeafMessage
{
private:
String value;
public:
StringMessage(const char * val = "");
StringMessage(MessageType type, const char * val = "");
~StringMessage(void);
void Compress(Compressor&amp; data) const;
bool Decompress(Decompressor&amp; data);
void Visit(Visitor * visitor) const;
void FillVisit(Visitor * visitor);
};

/*
Leaf Message type used to store a short value.
*/
class ShortMessage : public LeafMessage
{
private:
short value;
public:
ShortMessage(short val = 0);
ShortMessage(MessageType type, short val = 0);
~ShortMessage(void);
void Compress(Compressor&amp; data) const;
bool Decompress(Decompressor&amp; data);
void Visit(Visitor * visitor) const;
void FillVisit(Visitor * visitor);
};

/*
Leaf Message type used to store an unsigned short value.
*/
class UnsignedShortMessage : public LeafMessage
{
private:
unsigned short value;
public:
UnsignedShortMessage(unsigned short val = 0);
UnsignedShortMessage(MessageType type, unsigned short val = 0);
~UnsignedShortMessage(void);
void Compress(Compressor&amp; data) const;
bool Decompress(Decompressor&amp; data);
void Visit(Visitor * visitor) const;
void FillVisit(Visitor * visitor);
};

/*
Leaf Message type used to store a float value.
*/
class FloatMessage : public LeafMessage
{
private:
float value;
public:
FloatMessage(float val = 0.0F);
FloatMessage(MessageType type, float val = 0.0F);
~FloatMessage(void);
void Compress(Compressor&amp; data) const;
bool Decompress(Decompressor&amp; data);
void Visit(Visitor * visitor) const;
void FillVisit(Visitor * visitor);
};

/*
The MessageTypeManager class is a supportive class for the Composite Message system,
and defines / can define a list of factory methods that assemble a Composite Message.

Optionally, parameters can be passed to the factory method of each message type,
which contain the data to be assigned to the nodes of the composed message.
However, keep in mind that empty composed messages should also be created,
for when a Message is received but not decompressed yet.

I've only put a few examples in this class, cba to do all current message types.
There's a description of each message type in their implementations, see the .cpp file
for information and usage etc.

In the examples put into those comments, pay particular attention to the lack of casts
to a specific message type. All messages, when received, are cast into a CompositeMessage
type - none of the underlying classes are ever directly used by a client.

In a system where all Messages have been replaced by CompositeMessages, a ReceiveMessage
method would only have to do a single cast at the top of the method, from C4's Message
to this CompositeMessage type. A massive reduction in casts is a result, and a result from
that is more reliable and type-safe code.
*/
class MessageTypeManager
{
public:
static CompositeMessage * GetServerInfoMessage(long playerCount = 0L, long maxPlayerCount = 0L, String gameName = "", ResourceName worldName = "");
static CompositeMessage * GetGameInfoMessage(unsigned long flags = 0L, ResourceName world = "");
static CompositeMessage * GetUpdateScoreMessage(long playerScore = 0L);
static CompositeMessage * GetUpdateHealthMessage(long playerHealth = 0L);
static CompositeMessage * GetClientOrientationMessage(float azimuth = 0.0F, float altitude = 0.0F);
};

}

#endif

CompositeMessage.cpp
<pre name="code" class="cpp">#include "CompositeMessage.h"

#include "MGMultiplayer.h" // message types

using namespace C4;

Visitor::Visitor()
{
// set all 'current X value' indicator to 0.
currentLongValue = 0L;
currentUnsignedLongValue = 0L;
currentBoolValue = 0L;
currentFloatValue = 0L;
currentStringValue = 0L;
currentCharValue = 0L;
currentUnsignedCharValue = 0L;
currentShortValue = 0L;
currentUnsignedShortValue = 0L;
currentLong64Value = 0L;
currentUnsignedLong64Value = 0L;
}

Visitor::~Visitor()
{
}

// Adds a long value to the array.
void Visitor::AddLongValue(long value)
{
longValues.AddElement(value);
}

// Gets a long value from the array, or 0 if the array will exceed its bounds.
long Visitor::GetLongValue(void)
{
if (currentLongValue &gt;= longValues.GetElementCount())
return 0;
else
return (longValues[currentLongValue++]);
}

// Adds an unsigned long value to the array.
void Visitor::AddUnsignedLongValue(unsigned long value){
unsignedLongValues.AddElement(value);
}

// Gets an unsigned long value from the array, or 0 if the array will exceed its bounds.
unsigned long Visitor::GetUnsignedLongValue(void){
if (currentUnsignedLongValue &gt;= unsignedLongValues.GetElementCount())
return 0;
else
return (unsignedLongValues[currentUnsignedLongValue++]);
}

void Visitor::AddBoolValue(bool value){
boolValues.AddElement(value);
}

bool Visitor::GetBoolValue(void){
if (currentBoolValue &gt;= boolValues.GetElementCount())
return false;
else
return (boolValues[currentBoolValue++]);
}

void Visitor::AddFloatValue(float value){
floatValues.AddElement(value);
}

float Visitor::GetFloatValue(void){
if (currentFloatValue &gt;= floatValues.GetElementCount())
return false;
else
return (floatValues[currentFloatValue++]);
}

void Visitor::AddStringValue(const char * value){
stringValues.AddElement(value);
}

const char * Visitor::GetStringValue(void){
if (currentStringValue &gt;= stringValues.GetElementCount())
return &#8220;&#8221;;
else
return (stringValues[currentStringValue++]);
}

void Visitor::AddCharValue(char value){
charValues.AddElement(value);
}

char Visitor::GetCharValue(void){
if (currentCharValue &gt;= charValues.GetElementCount())
return &#8216; &#8216;;
else
return (charValues[currentCharValue++]);
}

void Visitor::AddUnsignedCharValue(unsigned char value){
unsignedCharValues.AddElement(value);
}

unsigned char Visitor::GetUnsignedCharValue(void){
if (currentUnsignedCharValue &gt;= charValues.GetElementCount())
return &#8216; &#8216;;
else
return (unsignedCharValues[currentUnsignedCharValue++]);
}

void Visitor::AddShortValue(short value){
shortValues.AddElement(value);
}

short Visitor::GetShortValue(void){
if (currentShortValue &gt;= shortValues.GetElementCount())
return 0;
else
return (shortValues[currentShortValue++]);
}

void Visitor::AddUnsignedShortValue(unsigned short value){
unsignedShortValues.AddElement(value);
}

unsigned short Visitor::GetUnsignedShortValue(void){
if (currentUnsignedShortValue &gt;= unsignedShortValues.GetElementCount())
return 0;
else
return (unsignedShortValues[currentUnsignedShortValue++]);
}

void Visitor::AddLong64Value(long64 value){
long64Values.AddElement(value);
}

long64 Visitor::GetLong64Value(void)
{
if (currentLong64Value &gt;= long64Values.GetElementCount())
return 0;
else
return (long64Values[currentLong64Value++]);
}

void Visitor::AddUnsignedLong64Value(ulong64 value){
unsignedLong64Values.AddElement(value);
}

ulong64 Visitor::GetUnsignedLong64Value(void){
if (currentUnsignedLong64Value &gt;= unsignedLong64Values.GetElementCount())
return 0;
else
return (unsignedLong64Values[currentUnsignedLong64Value++]);
}

// Compsite Message implementation.

// Constructor calls the parent constructor, passing the type parameter.
CompositeMessage::CompositeMessage(MessageType type) : Message(type){}

CompositeMessage::~CompositeMessage(void){}

void CompositeMessage::Compress(Compressor &amp;data) const{}

bool CompositeMessage::Decompress(Decompressor &amp;data) {return true;}

void CompositeMessage::Add(CompositeMessage * subnode) {}

void CompositeMessage::Visit(C4::Visitor * visitor) const {}

void CompositeMessage::FillVisit(C4::Visitor * visitor){}

/*
Creates a Visitor object and passes it to the Visit method, which
is implemented differently depending on what subclass of CompositeMessage
is currently used. When passed, the Visitor is returned.
*/
Visitor * CompositeMessage::GetData(void) const {
Visitor * visitor = new Visitor();
Visit(visitor);
return visitor;
}

// LeafMessage constructor, calls the parent CompositeMessage constructor
// passing the type parameter to it.
LeafMessage::LeafMessage(MessageType type) : CompositeMessage(type){}

LeafMessage::~LeafMessage(void){}

void LeafMessage::Compress(Compressor&amp; data) const {}

bool LeafMessage::Decompress(Decompressor&amp; data) {return true;}

void LeafMessage::Visit(Visitor * visitor) const {}

void LeafMessage::FillVisit(Visitor * visitor) {}

/*
ComposedMessage implementation.
*/
ComposedMessage::ComposedMessage(MessageType type) : CompositeMessage(type) {}

// deletes all the subnodes (if any) recursively.
ComposedMessage::~ComposedMessage(void)
{
long count = subnodes.GetElementCount();
for (natural a = 0; a &lt; count; a++)
{
if (subnodes[a]) delete subnodes[a];
}
}

// Adds the given element to the subnode array.
void ComposedMessage::Add(CompositeMessage * subnode)
{
subnodes.AddElement(subnode);
}

// Passes the Compressor to all subnodes&#8217; Compress methods.
void ComposedMessage::Compress(Compressor&amp; data) const
{
long count = subnodes.GetElementCount();
for (natural a = 0; a &lt; count; a++)
{
if (subnodes[a]) subnodes[a]-&gt;Compress(data);
}
}

// Passes the Decompressor to all subnodes&#8217; Decompress methods.
bool ComposedMessage::Decompress(Decompressor &amp;data)
{
long count = subnodes.GetElementCount();
for (natural a = 0; a &lt; count; a++)
{
if (subnodes[a])
{
if (!(subnodes[a]-&gt;Decompress(data)))
return false;
}
}
return true;
}

// Passes the Visitor object to all subnodes&#8217; Visit methods.
void ComposedMessage::Visit(Visitor * visitor) const
{
long count = subnodes.GetElementCount();
for (natural a = 0; a &lt; count; a++)
{
if (subnodes[a])
subnodes[a]-&gt;Visit(visitor);
}
}

// Passes the Visitor object to all subnodes&#8217; FillVisit methods.
void ComposedMessage::FillVisit(Visitor *visitor)
{
long count = subnodes.GetElementCount();
for (natural a = 0; a &lt; count; a++)
{
if (subnodes[a])
subnodes[a]-&gt;FillVisit(visitor);
}
}

/*
BoolMessage implementation
*/
BoolMessage::BoolMessage(bool val) : LeafMessage(kMessageBool)
{
value = val;
}

BoolMessage::BoolMessage(MessageType type, bool val) : LeafMessage(type)
{
value = val;
}

BoolMessage::~BoolMessage(void) {}

void BoolMessage::Compress(Compressor&amp; data) const
{
data &lt;&lt; value;
}

bool BoolMessage::Decompress(Decompressor&amp; data)
{
data &gt;&gt; value;
return (true);
}

void BoolMessage::Visit(Visitor * visitor) const
{
visitor-&gt;AddBoolValue(value);
}

void BoolMessage::FillVisit(Visitor *visitor)
{
value = visitor-&gt;GetBoolValue();
}

/*
LongMessage implementation
*/
LongMessage::LongMessage(long val) : LeafMessage(kMessageLong)
{
value = val;
}

LongMessage::LongMessage(MessageType type, long val) : LeafMessage(type)
{
value = val;
}

LongMessage::~LongMessage(void) {}

void LongMessage::Compress(Compressor &amp;data) const
{
data &lt;&lt; value;
}

bool LongMessage::Decompress(C4::Decompressor &amp;data)
{
data &gt;&gt; value;
return (true);
}

void LongMessage::Visit(Visitor * visitor) const
{
visitor-&gt;AddLongValue(value);
}

void LongMessage::FillVisit(Visitor * visitor)
{
value = visitor-&gt;GetLongValue();
}

/*
UnsignedLongMessage implementation
*/
UnsignedLongMessage::UnsignedLongMessage(unsigned long val) : LeafMessage(kMessageUnsignedLong)
{
value = val;
}

UnsignedLongMessage::UnsignedLongMessage(unsigned long val, MessageType type) : LeafMessage(type)
{
value = val;
}

UnsignedLongMessage::~UnsignedLongMessage(void) {}

void UnsignedLongMessage::Compress(Compressor &amp;data) const
{
data &lt;&lt; value;
}

bool UnsignedLongMessage::Decompress(C4::Decompressor &amp;data)
{
data &gt;&gt; value;
return (true);
}

void UnsignedLongMessage::Visit(Visitor * visitor) const
{
visitor-&gt;AddUnsignedLongValue(value);
}

void UnsignedLongMessage::FillVisit(Visitor * visitor)
{
value = visitor-&gt;GetUnsignedLongValue();
}

/*
Long64Message implementation
*/
Long64Message::Long64Message(long64 val) : LeafMessage(kMessageLong64)
{
value = val;
}

Long64Message::Long64Message(MessageType type, long64 val) : LeafMessage(type)
{
value = val;
}

Long64Message::~Long64Message(void) {}

void Long64Message::Compress(Compressor &amp;data) const
{
data &lt;&lt; value;
}

bool Long64Message::Decompress(C4::Decompressor &amp;data)
{
data &gt;&gt; value;
return (true);
}

void Long64Message::Visit(Visitor * visitor) const
{
visitor-&gt;AddLong64Value(value);
}

void Long64Message::FillVisit(Visitor * visitor)
{
value = visitor-&gt;GetLong64Value();
}

/*
UnsignedLong64Message implementation
*/
UnsignedLong64Message::UnsignedLong64Message(ulong64 val) : LeafMessage(kMessageUnsignedLong64)
{
value = val;
}

UnsignedLong64Message::UnsignedLong64Message(MessageType type, ulong64 val) : LeafMessage(type)
{
value = val;
}

UnsignedLong64Message::~UnsignedLong64Message(void) {}

void UnsignedLong64Message::Compress(Compressor &amp;data) const
{
data &lt;&lt; value;
}

bool UnsignedLong64Message::Decompress(C4::Decompressor &amp;data)
{
data &gt;&gt; value;
return (true);
}

void UnsignedLong64Message::Visit(Visitor * visitor) const
{
visitor-&gt;AddUnsignedLong64Value(value);
}

void UnsignedLong64Message::FillVisit(Visitor * visitor)
{
value = visitor-&gt;GetUnsignedLong64Value();
}

/*
CharMessage implementation
*/

CharMessage::CharMessage(char val) : LeafMessage(kMessageChar)
{
value = val;
}

CharMessage::CharMessage(MessageType type, char val) : LeafMessage(type)
{
value = val;
}

CharMessage::~CharMessage(void) {}

void CharMessage::Compress(Compressor &amp;data) const
{
data &lt;&lt; value;
}

bool CharMessage::Decompress(C4::Decompressor &amp;data)
{
data &gt;&gt; value;
return (true);
}

void CharMessage::Visit(Visitor * visitor) const
{
visitor-&gt;AddCharValue(value);
}

void CharMessage::FillVisit(Visitor * visitor)
{
value = visitor-&gt;GetCharValue();
}

/*
UnsignedCharMessage implementation
*/
UnsignedCharMessage::UnsignedCharMessage(unsigned char val) : LeafMessage(kMessageUnsignedChar)
{
value = val;
}

UnsignedCharMessage::UnsignedCharMessage(MessageType type, unsigned char val) : LeafMessage(type)
{
value = val;
}

UnsignedCharMessage::~UnsignedCharMessage(void) {}

void UnsignedCharMessage::Compress(Compressor &amp;data) const
{
data &lt;&lt; value;
}

bool UnsignedCharMessage::Decompress(C4::Decompressor &amp;data)
{
data &gt;&gt; value;
return (true);
}

void UnsignedCharMessage::Visit(Visitor * visitor) const
{
visitor-&gt;AddUnsignedCharValue(value);
}

void UnsignedCharMessage::FillVisit(Visitor * visitor)
{
value = visitor-&gt;GetUnsignedCharValue();
}

/*
StringMessage implementation
*/
StringMessage::StringMessage(const char *val) : LeafMessage(kMessageString)
{
value = val;
}

StringMessage::StringMessage(MessageType type, const char *val) : LeafMessage(type)
{
value = val;
}

StringMessage::~StringMessage(void) {}

void StringMessage::Compress(Compressor &amp;data) const
{
data &lt;&lt; value;
}

bool StringMessage::Decompress(C4::Decompressor &amp;data)
{
data &gt;&gt; value;
return (true);
}

void StringMessage::Visit(Visitor * visitor) const
{
visitor-&gt;AddStringValue(value);
}

void StringMessage::FillVisit(Visitor * visitor)
{
value = visitor-&gt;GetStringValue();
}

/*
ShortMessage implementation
*/
ShortMessage::ShortMessage(short val) : LeafMessage(kMessageShort)
{
value = val;
}

ShortMessage::ShortMessage(MessageType type, short val) : LeafMessage(type)
{
value = val;
}

ShortMessage::~ShortMessage(void) {}

void ShortMessage::Compress(Compressor &amp;data) const
{
data &lt;&lt; value;
}

bool ShortMessage::Decompress(C4::Decompressor &amp;data)
{
data &gt;&gt; value;
return (true);
}

void ShortMessage::Visit(Visitor * visitor) const
{
visitor-&gt;AddShortValue(value);
}

void ShortMessage::FillVisit(Visitor * visitor)
{
value = visitor-&gt;GetShortValue();
}

/*
UnsignedShortMessage implementation
*/
UnsignedShortMessage::UnsignedShortMessage(unsigned short val) : LeafMessage(kMessageUnsignedShort)
{
value = val;
}

UnsignedShortMessage::UnsignedShortMessage(MessageType type, unsigned short val) : LeafMessage(type)
{
value = val;
}

UnsignedShortMessage::~UnsignedShortMessage(void) {}

void UnsignedShortMessage::Compress(Compressor &amp;data) const
{
data &lt;&lt; value;
}

bool UnsignedShortMessage::Decompress(C4::Decompressor &amp;data)
{
data &gt;&gt; value;
return (true);
}

void UnsignedShortMessage::Visit(Visitor * visitor) const
{
visitor-&gt;AddUnsignedShortValue(value);
}

void UnsignedShortMessage::FillVisit(Visitor * visitor)
{
value = visitor-&gt;GetUnsignedShortValue();
}

/*
FloatMessage implementation
*/
FloatMessage::FloatMessage(float val) : LeafMessage(kMessageFloat)
{
value = val;
}

FloatMessage::FloatMessage(MessageType type, float val) : LeafMessage(type)
{
value = val;
}

FloatMessage::~FloatMessage(void) {}

void FloatMessage::Compress(Compressor &amp;data) const
{
data &lt;&lt; value;
}

bool FloatMessage::Decompress(C4::Decompressor &amp;data)
{
data &gt;&gt; value;
return (true);
}

void FloatMessage::Visit(Visitor * visitor) const
{
visitor-&gt;AddFloatValue(value);
}

void FloatMessage::FillVisit(Visitor * visitor)
{
value = visitor-&gt;GetFloatValue();
}

/*
Creates and returns a CompositeMessage containing two long values and two string values.
Usage:

Creating new filled ServerInfoMessage composite message:

// parameters are all the params you want to send.
CompositeMessage * message = MessageTypeManager::GetServerInfoMessage(playerCount, maxPlayerCount, gameName, worldName);
TheMessageMgr-&gt;SendMessage(addressee, *message);
// (note that there should be a star in front of the &#8216;message&#8217; param in the sendmessage method, since the
// GetServerInfoMessage method returns a pointer to the message, whereas the SendMessage method expects
// a reference instead.

// Also, the message should probably be deleted after this, but I dunno if the message is sent right
// away or stored in a cache for a while, which could lead to unexpected results if the message is deleted.

Receiving incoming ServerInfoMessage composite message type:

CompositeMessage * msg = static_cast(message);
Visitor * v = msg-&gt;GetData();

long playerCount = v-&gt;GetLongValue();
long maxPlayerCount = v-&gt;GetLongValue();
String gameName = v-&gt;GetStringValue();
ResourceName worldName = v-&gt;GetStringValue();

// note that the order of inserting and extracting data of the same type should be the same on both
// the sending and receiving side.
*/
CompositeMessage * MessageTypeManager::GetServerInfoMessage(long playerCount, long maxPlayerCount, String gameName, ResourceName worldName)
{
CompositeMessage * message = new ComposedMessage(kMessageServerInfo);
message-&gt;Add(new LongMessage(playerCount));
message-&gt;Add(new LongMessage(maxPlayerCount));
message-&gt;Add(new StringMessage(gameName));
message-&gt;Add(new StringMessage(worldName));
return message;
}

/*
Creates and returns a GameInfoMessage composite message type, containing an unsigned long and a string value.

Usage:

CompositeMessage * message = MessageTypeManager::GetGameInfoMessage(multiplayerFlags, worldName);
TheMessageMgr-&gt;SendMessage(addressee, *message);

// extracting

CompositeMessage * msg = static_cast(message);
Visitor * v = msg-&gt;GetData();

unsigned long flags = v-&gt;GetUnsignedLongValue();
ResourceName world = v-&gt;GetStringValue();
*/
CompositeMessage * MessageTypeManager::GetGameInfoMessage(unsigned long flags, ResourceName world)
{
CompositeMessage * message = new ComposedMessage(kMessageGameInfo);
message-&gt;Add(new UnsignedLongMessage(flags));
message-&gt;Add(new StringMessage(world));
return message;
}

/*
Creates and returns an UpdateScoreMessage, which contains a single Long value.
Notice that in this case, a LongMessage is returned directly without first having
to put it into a ComposedMessage - the advantage of using a proper abstract class.
Receiving parties will just treat it like any other CompositeMessage, as in,
they won&#8217;t be able nor will they have to see the difference between the two.

Usage:

// send
TheMessageMgr-&gt;SendMessage(addressee, *MessageTypeManager::GetUpdateScoreMessage(playerScore));

// receive

long score = static_cast(message)-&gt;GetData()-&gt;GetLongValue();
*/
CompositeMessage * MessageTypeManager::GetUpdateScoreMessage(long playerScore)
{
return (new LongMessage(kMessageUpdateScore, playerScore));
}

/*
Creates and returns a new UpdateHealthMessage, which has the same structure of
GetUpdateScoreMessage. The only difference between the two is the message identification
number. We could make the two even simpler, by defining and implementing a
CreateLongMessage method, which takes a message identifier and an initial value,
and returns a LongMessage with that value. GetUpdateHealthMessage and GetUpdateScoreMessage
could then both call and return the return value of that GetLongMessage method, passing
their own message type identifier to the method. We won&#8217;t do that in here though,
to keep things straightforward for now.

Usage:

// send
TheMessageMgr-&gt;SendMessage(addressee, *MessageTypeManager::GetUpdateHealthMessage(playerHealth));

// receive

long playerHealth = static_cast(message)-&gt;GetData()-&gt;GetLongValue();

*/
CompositeMessage * MessageTypeManager::GetUpdateHealthMessage(long playerHealth)
{
return new LongMessage(kMessageUpdateHealth, playerHealth);
}

/*
Creates and returns a ClientOrientation CompositeMessage, which contains two float values.

Usage:

Send:
TheMessageMgr-&gt;SendMessage(addressee, MessageTypeManager::GetClientOrientationMessage(azimuth, altitude));

Receive:

Visitor * v = static_cast(message)-&gt;GetData();
float azimuth = v-&gt;GetFloatValue();
float altitude = v-&gt;GetFloatValue();

*/
CompositeMessage * MessageTypeManager::GetClientOrientationMessage(float azimuth, float altitude)
{
CompositeMessage * message = new ComposedMessage(kMessageClientOrientation);
message-&gt;Add(new FloatMessage(azimuth));
message-&gt;Add(new FloatMessage(altitude));
return message;
}</pre>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://greatjustice.info/applied-design-patterns-c4-engine-messages/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The C4 Engine</title>
		<link>http://greatjustice.info/the-c4-engine/</link>
		<comments>http://greatjustice.info/the-c4-engine/#comments</comments>
		<pubDate>Mon, 14 Jul 2008 08:06:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[C++]]></category>

		<category><![CDATA[General]]></category>

		<category><![CDATA[3D engine]]></category>

		<category><![CDATA[C4 engine]]></category>

		<category><![CDATA[games]]></category>

		<guid isPermaLink="false">http://greatjustice.info/?p=25</guid>
		<description><![CDATA[During the last 20 weeks (February to June &#8216;08), I and 7 other people have been working on a game project (both for university points and for this online group of dudes that started the creation of this particular game), 2 of them programmers, 5 of them artsy fags media students (who did models, textures, [...]]]></description>
			<content:encoded><![CDATA[<p>During the last 20 weeks (February to June &#8216;08), I and 7 other people have been working on a game project (both for university points and for this online group of dudes that started the creation of this particular game), 2 of them programmers, 5 of them artsy fags media students (who did models, textures, sketches, sound/music etc).</p>
<p>The game itself is a sci-fi tactical first person shooter (well, it&#8217;s supposed to be in a distant future, olz), which was basically in a half-assed concept stage for about a year or two, during which some very nice concept art drawings were made, but nothing concrete was made, such as actual game design (i.e. functional design) or background story.</p>
<p>The project was eventually put forward to our university as a project for the Game Design minor, and since then, we&#8217;ve been working on it for the last 20 weeks. In this post, I won&#8217;t go into detail about the project itself, but more into the 3D engine that was used: <a href="http://terathon.com/c4engine">The C4 engine</a>. <span id="more-25"></span></p>
<h2>About</h2>
<p>The C4 Engine is written and maintained by Eric Lengyel, a mathematician slash application developer, who&#8217;s worked on the technologies behind several games, including several PS3 titles (although no actual names are given). He&#8217;s also written some or contributed to some books, including <a title="Mathematics for 3D Game Programming and Computer Graphics at Amazon" href="http://www.amazon.com/exec/obidos/redirect?tag=terathon-20&amp;path=tg/detail/-/1584502770" target="_blank">Mathematics for 3D Game Programming And Computer Graphics</a>, so he bascially knows what he&#8217;s talking about.</p>
<p>C4&#8217;s got a load of features, including all the basic graphics capabilities one would want for a game, as well as a built-in world editor, graphical script editor, etc. The next version, 149, which is out now for licensed users, has a greatly improved graphical script editor, with conditionals and variables and whatnot (it didn&#8217;t have those earlier). Version 1.5, to be released late August if everything&#8217;s right, will come with a terrain editor and large outdoor terrain support (as in, the current version is mainly suitable for indoor or &#8216;roomed&#8217; environments, which can be divided into so-called zones, which are used to determine what has to be rendered etc).</p>
<p>For more info on C4&#8217;s features, look <a title="C4 Engine features" href="http://www.terathon.com/c4engine/features.php" target="_blank">here</a>.</p>
<p>The C4 engine is aimed at both professional users and &#8216;indie&#8217; game developers (independent, hobbyists, students etc). For both types, a license can be aquired. The indie category, such as we are, can get a license for as low as $200.-, which gives the licensee a lifetime license (= free updates to later versions), and allows 5 people to work on the engine and the engine&#8217;s code. However, this license type will be updated when version 1.5 (150) is released, and will be upped to $350,- accoring to <a title="C4 Engine homepage" href="http://terathon.com/c4engine" target="_blank">the C4 website</a>.  The engine is supplied as both the executables, plugins and, something unique, the full source code to both the engine and the demo game. That means that programmers can edit or add features to the engine itself, and get a deeper insight into the workings of the engine by reading its code.  According to the <a title="C4 engine news, Lockheed Martin and universities taking licenses for the engine." href="http://www.terathon.com/c4engine/news.php" target="_blank">C4 engine&#8217;s website</a>, some large corporations (such as Lockheed Martin) and universities have taken licenses for the C4 engine.</p>
<p></p>
<h2>Screenshots</h2>
<p>Let&#8217;s goan see some screenshots from the current demo game which, by the way, doesn&#8217;t show off the full potential of the demo game. The full-sized screenshots can be viewed <a title="C4 engine screenshots" href="http://www.terathon.com/c4engine/shots.php" target="_blank">here</a>.</p>
<p><a href="http://greatjustice.info/wp-content/pipes1x.jpg"><img class="alignnone size-medium wp-image-29" title="pipes1x" src="http://greatjustice.info/wp-content/pipes1x-300x225.jpg" alt="Pipes in C4, showing cube light." width="300" height="225" /></a></p>
<p>This first image shows a basic piece of a level with a so-called cube light, a light that basically projects a texture 360 degrees around it. In this case, it projects the insides of a lantern.</p>
<p><a href="http://greatjustice.info/wp-content/cemetery1x.jpg"><img class="alignnone size-medium wp-image-30" title="cemetery1x" src="http://greatjustice.info/wp-content/cemetery1x-300x225.jpg" alt="Cemetery level in C4, showing off fog effects." width="300" height="225" /></a></p>
<p>This next image displays a scene from the Cemetery level, a relatively new demo level. This particular screenshot displays an imported terrain (not using the terrain editor yet btw, just the height map import option), with a fog layer on top of it. The fog&#8217;s fully configureable, so you can set the height at which it starts, the color, the density, etc.</p>
<p>A feature not shown in this screenshot is the lightning effect, which lights up the entire level and plays thunder sounds and such. Once again, this isn&#8217;t a level that&#8217;s graphically the most impressive, just a limited feature showcase - see some of the <a title="C4 Engine screenshots" href="http://www.terathon.com/c4engine/shots.php" target="_blank">screenshots</a> for other games made with C4 for better examples.</p>
<p>The Ravensword game screenshots shows how good proper normal maps can look (normal map is a texture that contains height information, which is used to calculate shadows on the object itself, which translates to a perception of depth and detail). The screenshots for World of Subways (yes, a subway simulator game) look in roughly the same style as Half-Life 2, only more realistic (and with less zombies).</p>
<p><a href="http://greatjustice.info/wp-content/trees3x.jpg"><img class="alignnone size-medium wp-image-32" title="trees3x" src="http://greatjustice.info/wp-content/trees3x-300x225.jpg" alt="C4 engine demo level showing water effects, waterfall effect, terrain" width="300" height="225" /></a></p>
<p>The above screenshot is taken from the primary demo level, and shows imported terrain for the overall layout of the land, a waterfall effect (made with C4&#8217;s particle system), water itself (which uses animated textures and portals for reflection / refraction, see also <a title="Creating a lake level with height maps and water in the C4 engine" href="http://terathon.com/wiki/index.php?title=Creating_a_Basic_World_-_Part_2" target="_blank">this tutorial</a> on C4&#8217;s wiki on how the water effect was made.) , etcetera.</p>
<p><a href="http://greatjustice.info/wp-content/editorx.jpg"><img class="alignnone size-medium wp-image-31" title="editorx" src="http://greatjustice.info/wp-content/editorx-300x225.jpg" alt="The C4 Engine world editor, showing a scene graph, a frontal view, and a perspective view." width="300" height="225" /></a></p>
<p>This next screenshot is of C4&#8217;s built-in world editor, which allows people to make their own worlds. On the left side is a menu bar, which contains all the tools a world editor can use. The pane next to that is the Scene Graph, a graphical representation of the internal structure of a world editor. A root node, the Infinite Zone, contains a handful of subnodes, such as geometries, light sources, etcetera, which in turn can contain several subnodes as well.</p>
<p><a href="http://greatjustice.info/wp-content/scriptx.jpg"><img class="alignnone size-medium wp-image-33" title="scriptx" src="http://greatjustice.info/wp-content/scriptx-300x225.jpg" alt="A screenshot of the C4 engine\'s graphical script editor" width="300" height="225" /></a></p>
<p>The above is a screenshot of C4&#8217;s graphical script editor, I&#8217;m fairly sure this is the old (or current) version. Version 149 of the engine, to be released soon, contains additional features that could, once fully developed, allow non-programmers to program the behavior of an NPC, for example.</p>
<p></p>
<h2>Experiences</h2>
<p>Anyways, this was supposed to be more of a review and experiences with the C4 engine, but eh, it&#8217;ll need a good intro in order for people to sorta know what we&#8217;re talking about.</p>
<p>We&#8217;ve spent a good 20 weeks on our project, half of which was spent designing our game and exploring the C4 engine. We played around and made some basic worlds with the world editor, dived into the demo game&#8217;s code and edited some stuff, added a weapon by following <a title="Tutorial: Adding a weapon in C4." href="http://www.terathon.com/wiki/index.php?title=Adding_a_Weapon_into_C4" target="_blank">a tutorial</a>, etcetera.</p>
<p>It was pretty daunting to begin with for several reasons:</p>
<ul>
<li>A new language. Up until this project, all 3 of us (we had 3 programmers in our group) had little to no experience programming in C++ - I myself had done a fractal generator largely copied from the internets during a 2-week period. So with the C4 engine (which is written in C++, in case you didn&#8217;t realize that by now), we encountered new, unexplored problems like pointers and such. Scary.</li>
<li>A new environment. The C4 engine&#8217;s quite different from the Java libraries and such I&#8217;ve used before this, with a lot of tricks and such. For example, a lot of binary flags are used - basically a means of storing a large amount of boolean data into a single variable. But that was all learnable.</li>
<li>Poorly designed demo game. The engine itself is designed properly, but the demo game&#8217;s code looks as if it was programmed in some free saturday afternoons. There&#8217;s 500-lined functions containing large switch-statements which contain logic for pretty much all components for the demo game, to name an example. More on that later.</li>
<li>Lack of commenting / documentation. The C4 engine&#8217;s code itself is reasonably documented (it&#8217;s not entirely complete and in a format that basically forces you to view <a title="C4 Engine code documentation." href="http://www.terathon.com/c4engine/doco/" target="_blank">the online version</a>),  but the demo game itself isn&#8217;t. There are some scarce one or two-lined comments in particular bits of code, but not by far complete. So in order to understand the inner workings of the demo game, we had to dive into the code itself and work according to some of the tutorials on the <a title="C4 Engine wiki" href="http://www.terathon.com/wiki/" target="_blank">C4 wiki</a>.  But after some time, we got the hang of it and knew enough of both the engine and the demo game&#8217;s code to add most of the features we wanted.</li>
</ul>
<p>We added our own weapons (a handgun and an assault rifle), some of our own models (not all, which is why we didn&#8217;t get all the points for the end-product), animations (and animation control), sounds, and our own special features - distraction grenades, one that generated a &#8216;hologram&#8217;, one that played a sound, and one that displayed a flashing light pattern (which is supposed to look like gunfire). All three configureable by the player (by using an in-game selection menu), etc. They were all fired by the C4 demo game&#8217;s grenade launcher, but it&#8217;s the idea that counts.</p>
<p>We also added teams to the players (a multiplayer mode was already available), 3 game modes, and did some refactorings by splitting up some of the classes into their own files (a habit from Java, counteracted by the habit of whoever wrote the demo game to put loads of similar classes into a single file).  The end result was a game that displayed most of the features we had planned, but didn&#8217;t look as good and looked basically only half-finished, due to the lack of models and the levels being only half-finished. But I myself got most points, mainly due to programming.</p>
<p>Anyways, the C4 engine left a very good overall impression on me. I haven&#8217;t had any experience with other game engines (that is, unless you count <a title="ZZT on Wikipedia" href="http://en.wikipedia.org/wiki/ZZT" target="_blank">ZZT</a> as being a game engine), but those that do think that C4&#8217;s the most awesome and well thought-out engines they&#8217;ve encountered so far. The engine itself is very rich in features without looking cluttered or bloated, and is still in full development, a new version with new features being released every month or so. We started when the engine was at version 147, and when we were done, version 149 beta 2 was out. A few days ago, the final version of 149 was released, along with <a title="C4 Engine Demo Download Page" href="http://www.terathon.com/c4engine/download.php" target="_blank">a new demo</a> including new demo levels and everything.</p>
<h2>Criticisms</h2>
<p>The majority of criticisms we as programmers had on the engine was all in its demo game and the documentation. The code-level documentation is allright (see above), but in terms of &#8216;how do you do so-and-so&#8217;, it&#8217;s still lacking. For example, halfway our project I wanted to find out how the C4 networking system worked. At that time, the only documentation avaiable was <a title="Networking Concepts on the C4 Engine Wiki" href="http://www.terathon.com/wiki/index.php?title=Networking_Concepts" target="_blank">an article on the C4 wik</a>i, highlighting the basic assumptions and workings of the network and messaging system, and the API documentation itself on the <a title="class Message in the C4 engine API" href="http://www.terathon.com/c4engine/doco/MessageMgr/Message.html" target="_blank">messages</a> and <a title="C4 Message Manager documentation" href="http://www.terathon.com/c4engine/doco/MessageMgr/MessageMgr.html" target="_blank">message manager</a>, which sends and handles messages, as well as the <a title="C4 engine documentation on the Network Manager class." href="http://www.terathon.com/c4engine/doco/NetworkMgr/NetworkMgr.html" target="_blank">network manager</a>, which operates on a lower level.</p>
<p>So because of that, we were bascially forced to figure it all our on ourselves, mainly trying to get as much information as possible from the API documentation and the code found in the demo game. Because we didn&#8217;t want others to have the same problem (and spend as much time on solving it), we (read: I) wrote a two-part tutorial on C4&#8217;s messaging system, in which a basic chat application is made. You can find that tutorial right <a title="Basic Network Tutorial on the C4 Engine Wiki." href="http://http://www.terathon.com/wiki/index.php?title=Basic_Network_Tutorial" target="_blank">here</a>, and part two <a title="Basic Network Tutorial part 2 on the C4 Engine Wiki." href="http://www.terathon.com/wiki/index.php?title=Basic_Network_Tutorial_-_Part_2" target="_blank">here</a>.</p>
<p>But yeah, not everything is as of yet documented and explained. There&#8217;s enough to get you going, but it&#8217;s just not all there yet.</p>
<p>The second major problem was the lack of design in the demo game. There&#8217;s at least a dozen examples to think of, but it&#8217;s kinda bollox to have to repeat them all here. I can do one example though, the weapon system in the demo game. According to <a title="Adding a weapon to the C4 demo on the C4 engine wiki" href="http://www.terathon.com/wiki/index.php?title=Adding_a_Weapon_into_C4" target="_blank">the tutorial on the C4 wiki on adding a weapon</a> to the demo game,  a programmer has to add two files to the project, and edit 12 (!) files to add it to the game. These files handle firing, selecting, picking up, ammo etc of the weapon. But the problem is that it&#8217;s so divided, it&#8217;s difficult to figure all that out on your own without the use of a tutorial. Not only that, but the weapon system is decentralized, or, to put it more bluntly, all over the place. There are .h and .cpp files for each type of weapon, but they don&#8217;t contain anything related to the weapon itself, only to the projectile fired by the weapon (if any). Firing the weapon happens in a very large method in the Fighter class, a controller for the player&#8217;s model, which is called each frame, checks if a timer has run down to 0, then checks what weapon is currently selected, re-sets the timer and calls a function that informs everyone that a projectile has been fired, which in turn generates a projectile and moves it every frame.</p>
<p>But that&#8217;s not how you&#8217;d want things to happen. You&#8217;d want each weapon to have its own files, and its own responsibilities.  You don&#8217;t want a fixed number somewhere in a very large method in the Fighter class to determine how fast a weapon fires, you want it to occur in the weapon&#8217;s file itself, and make it dynamic even if you think that&#8217;ll add something to your game or if you just want to tweak it.</p>
<p>And that&#8217;s just one example, there were at least 3 more specific modules of the demo game that were just designed&#8230; well, wrong. They worked fine, so functionally they were good, but their design was just awful (imo), everything was fixed at compile-time, loads of functionality was crammed into a single method, loads of responsibility into a single class, and so forth.</p>
<p>We didn&#8217;t have the time during our project to fix all this, so instead we (read: I) made a document in which the game&#8217;s modules are described, the problems occuring in those highlighted, and one or more solutions described and explained. I firstly put that up for assessment by the teachers (one for the techical design, the other for Written English), then offered it to the licensees and author of the C4 engine. So far, only two or three licensees have commented on it (both whom I doubt understand even half of what&#8217;s in there), and the author is yet to comment on it. He&#8217;s probably busy with the next version of the engine though, so I won&#8217;t blame him.</p>
<p>I&#8217;ve put the refactoring proposal online for your reading pleasure, maybe you can learn something from it. As I said on the forums when I posted it, any C&amp;C on it is welcome. Here&#8217;s the file:</p>
<p>Office 2007 version: <a href="http://greatjustice.info/wp-content/refactoring-proposal.docx">Refactoring Proposal</a></p>
<p>Office 1997-2003 version:  <a href="http://greatjustice.info/wp-content/refactoring-proposal.doc">Refactoring Proposal</a></p>
<p>It&#8217;s also an attempt at applying some design patterns, including the Composite, Visitor, Factory Method, and Prototype patterns. I&#8217;m sure that more patterns and refactorings can be applied to the demo game&#8217;s code, but the components described in the document should give a very good head start (if I say so myself, /smug). That, and if done right, could inspire others as well.</p>
<p>Currently, I&#8217;m finishing up on our project, and in order to get the last few points I&#8217;ve started to implement at least some of the refactorings proposed in the document into the C4 demo game, and publishing those refactorings on the forums. I probably won&#8217;t spend a lot of time on that anymore, since I haven&#8217;t had much feedback on the proposals, least of all from the author himself (i.e. the dude that actually matters). I even sent him a PM about the matter, but I&#8217;ve received no feedback whatsoever. Either he hasn&#8217;t gotten to it, or he&#8217;s just ignoring the whole thing - I&#8217;m suspecting the latter, and I don&#8217;t like it. But eh, it&#8217;s his product, and as such, his problem.</p>
<h2>Conclusion</h2>
<p>But, outside of the (in my opinion) poor design of the demo game, the C4 engine is pretty good. As said, I have no experience with other graphics engines, so I&#8217;m unable to provide a proper comparison, but from what I&#8217;ve seen of the C4 engine, its features, its relatively low price and all that, I&#8217;m impressed. It has pretty much everything anyone needs making a 3D video game, and the features it doesn&#8217;t have will be added in the coming versions. As I probably said in the beginning of this article, version 1.5 will add a terrain editor to the engine. I dunno how advanced it will be, but from <a title="Discussion on large terrain editors @ the C4 Engine forums" href="http://www.terathon.com/forums/viewtopic.php?f=24&amp;t=5160&amp;p=45768" target="_blank">what the author says about it</a>, it&#8217;ll be technically quite impressive. (note that the author of the engine isn&#8217;t the first poster in the linked thread, but the dude with the red username etc).</p>
<p>All in all, I think that from a bang-for-buck point of view, the C4 engine is the best engine any beginning game developer can buy. For inexperienced or unmotivated programmers it may have a steep learning curve (mainly due to the poor design of the demo game - it&#8217;s all in there, but it&#8217;s hard to get it out), but it&#8217;ll be well worth it. I only wish the demo game had a better design, &#8217;cause right now it&#8217;s putting people off. Not as much as they&#8217;ve been put off by other affordable engines (judging by some of the forum posts by previous users of said engines), but still.</p>
]]></content:encoded>
			<wfw:commentRss>http://greatjustice.info/the-c4-engine/feed/</wfw:commentRss>
		</item>
		<item>
		<title>University versus self-taught</title>
		<link>http://greatjustice.info/university-versus-self-taught/</link>
		<comments>http://greatjustice.info/university-versus-self-taught/#comments</comments>
		<pubDate>Sun, 22 Jun 2008 00:15:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://greatjustice.info/?p=24</guid>
		<description><![CDATA[A topic I&#8217;ve been thinking about for quite some time now. If I was an employer, looking for an employee, which would I take: The type that basically self-taught himself programming through reading books and/or websites, or the type that spend an X amount of years at university and has a bachelor&#8217;s or master&#8217;s degree? [...]]]></description>
			<content:encoded><![CDATA[<p>A topic I&#8217;ve been thinking about for quite some time now. If I was an employer, looking for an employee, which would I take: The type that basically self-taught himself programming through reading books and/or websites, or the type that spend an X amount of years at university and has a bachelor&#8217;s or master&#8217;s degree? Let&#8217;s assume that, when they apply, they both have roughly the same amount of knowledge and/or skill.</p>
<p>I&#8217;ll unveil it right now: I&#8217;d totally go for the one that went to university and got a degree. Why? I&#8217;ll explain (or, attempt to.) Read the rest of this post for a wider view of my opinion, as well as a massive edit written when this post got a relatively large amount of attention quite suddenly and unsuspectingly.</p>
<p><span id="more-24"></span></p>
<p>When someone both went to university and, more importantly, actually finished it, you&#8217;ll know that he has certain properties to himself. First, you&#8217;ll know that he&#8217;s persistent, in that he&#8217;s spent 4 or 6 years (or, he would in my country) learning a job, even though he didn&#8217;t like some parts of it. A self-educated programmer would more likely have stuck to only the languages and projects he himself liked. Over here, a student would have to perform various assignments in university, and some of them spanning multiple disciplines. I somehow doubt a self-educated programmer would be working on programming both a microprocessor and a (Java) control program for a remote-controlled model boat, at least not unless he had a particular interest in that area.</p>
<p>In university, you&#8217;re pretty much forced to perform a wide range of projects, spanning multiple disciplines, languages, areas, and forcing the student to work together with people of different environments - for example, electronical engineers, 3D modelers, structural engineers, etcetera. I do not believe that most self-taught programmers would have such a background. Instead, I&#8217;d expect them to remain in their own safe zone - PHP webapplications, C/C++ apps for an open source project or operating system, or .NET hobby-applications for, say, maintaining an address book - you name it.</p>
<p>I don&#8217;t actually know any self-taught programmers, mind, so feel free to prove me wrong. I&#8217;m confident that there&#8217;s numerous self-taught programmers that have a much wider range of software engineering interests than I can think of.</p>
<p>But yeah. University graduates would have several points above self-taught programmers, since they&#8217;ve been through a system, they&#8217;ve persisted in doing tasks they, most likely, didn&#8217;t really want to do. I had to work on completely unrelated projects like designing / describing an environmentally friendly house, which was more concentrated on structural engineering and whatnot than programming. But because of that, and other projects, I know (read: have a general idea) what goes on in those areas. I know what it takes to write a program at the very lowest levels of the system (well, not THAT low, considering we still could use C), where you&#8217;d only have 300~something <em>bytes</em> of memory available to do everything in.</p>
<p>Anyways, to conclude this post, I believe that a self-taught programmer does not have the persistence, organizational skills, multi-disciplinary development, and finally the proof of his ability (i.e. a piece of paper saying he&#8217;s finished an education) to be as desirable for a company as self-taught one is, some exceptions left aside.</p>
<p><strong>Massive edit</strong></p>
<p>Whoa, stepped on quite some toes here it seems, never thought my blog would draw so much attention. Guess linking to other blogs draws massive attention. That, and having the author of said blog directly link to this post. Let&#8217;s comment on some of the comments here.</p>
<p>First, I&#8217;m not (entirely) trying to say that the self-taught programmers are incompetent - the example of Bill Gates et al was raised, one that I agree with, since he and everyone else that started the whole science were pretty much all self-taught, in a time before degrees.</p>
<p>As for hiring people, the degree does, indeed, not mean anything when it comes to actual knowledge or experience - I&#8217;m actually still in university, and the people I work with&#8230; well, aren&#8217;t that awesome, in most cases. However, and this is one point I have, last year I worked with a handful of people that came along with my previous education (a system administrator education thingy), and to put it short, they were terrible. Lucky for me (since they&#8217;d most likely cling to me so I could do their job), they failed the second year and probably won&#8217;t finish the education.</p>
<p>Which is one of the points I was trying to get at while (hastily) writing this post: An education filters out most of the bad ones (some exceptions there), so you know that someone who finished an education has at least a minimal level of skill, a guarantee you can&#8217;t get from self-taught people. Of course, you can question people about it during a job interview or something, but a lot of people will say something like &#8220;I made websites so-and-so blah blah blah&#8221;, which only shows that they&#8217;ve got a basic understanding of a programming language and can produce something with it - it does not however tell anything about their grasp of, say, OO principles, design patterns, proper coding, working in a team, etcetera, or at least not without asking on.</p>
<p>Another thing is that 99% of employers, unfair as it may be, simply want you to have an education and, preferably, an X amount of experience, else they simply won&#8217;t even ask you for an interview, especially not if you can&#8217;t provide them with a list of experience or self-taught business.</p>
<p>There&#8217;s also a comment about actual experience versus theoretical knowledge, one that I also agree with. Someone can have all the theoretical knowledge he wants, but if he can&#8217;t put it into practice, he will fail. I have the advantage that I have that ability, plus some practical experience where I could put that theoretical stuff into practice , but I&#8217;m sure that many people wouldn&#8217;t and would be only theoretical masters.</p>
<p>I also do not believe that you can create programmers just from Wikipedia. It is a very good tool as a helper - I&#8217;ve used it loads as well -, but you can&#8217;t base everything just on that. Books are also just tools, eventually, it&#8217;s all about experience. And a college will give you, at least in my case, a basis of experience if you finish it. Over here, you get a total of a year of experience in a real-world company during two internships, where you can put the theory into practice - which, by the way, is far more valuable than the actual teaching. I spent my first 20 weeks at a large insurance company, who spent an entire floor on a single website (since it&#8217;s a large and critical website, not because they have loads of people that do nothing), and the experience I gained there was invaluable. There, they wouldn&#8217;t hire someone who did some websites in PHP or did some programs in .net, they&#8217;d hire people with degrees.</p>
<p>Realistically speaking, only a small portion of people would get at a proper enough level without an education to be hired, and the ones with a degree will get a much higher chance of a job.</p>
<p>Also, there&#8217;s several categories of self-taught people. There&#8217;s the really talented ones, that spent years in they mother&#8217;s basements (or whatever) programming for a wide range of various projects, and then there&#8217;s the hobby programmer. This latter one is mostly active on the internets, posting on blogs (like this one&#8230; oops) and whatnot telling the world what an awesome PHP database class they&#8217;ve written, or whatnot. These are the category of self-proclaimed programmers that they&#8217;re on top of the world, and these are the ones that I would not want to learn from. Which, sadly, I did a few years back.</p>
<p>There was this dude, a self-taught web developer in PHP, who boasted about all his projects and making $45 an hour (which, for his former Russian country, was a lot). He helped me out with my first actual project, replacing a horrid block of hundreds of lines of repetitive HTML / PHP forms into a 15-lined triple for-loop that did the exact same, only neater.</p>
<p>Later, I took a look at his code, and already didn&#8217;t feel too good about it. He built a website CMS in a week or so, and when he sold the site after two months of getting it, he dished in $6000,-, for a week of programming. Now, some years later and now I have part of an education behind me, I realize that he wasn&#8217;t actually that good of a programmer. Sure, he made money, and sure, his websites worked, but in terms of design, he failed. He used object-oriented programming (once again, self-proclaimed), but he used it in the exact wrong way. I should see if I can still find that code somewhere on my home computer, for the lulz.</p>
<p>The main category of self-taught programmers falls into that category - the one that think they&#8217;re all that, but aren&#8217;t. You probably won&#8217;t see that type applying for jobs, since either they think they&#8217;re too good for that, or they know nobody would hire them for their lack of an education, but instead they&#8217;ll fill the internets with their self-botched template systems and whatnot. The problem with that is that other people will read it, and the less smart will actually praise them for it and, worse, take over their code and habits, resulting in more self-educated programmers that do everything wrong. I can&#8217;t be arsed to collect examples at the moment, but they&#8217;re there allright.</p>
]]></content:encoded>
			<wfw:commentRss>http://greatjustice.info/university-versus-self-taught/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Applied design patterns: Database abstraction (part 2)</title>
		<link>http://greatjustice.info/applied-design-patterns-database-abstraction-part-2/</link>
		<comments>http://greatjustice.info/applied-design-patterns-database-abstraction-part-2/#comments</comments>
		<pubDate>Mon, 09 Jun 2008 18:21:32 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Design Patterns]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Databases]]></category>

		<guid isPermaLink="false">http://greatjustice.info/?p=20</guid>
		<description><![CDATA[In some of my previous posts, I&#8217;ve pretty much ranted about the poor design qualities of some people that enjoy calling themselves PHP programmers. In these two posts however, I&#8217;d like to show you what good and proper design is. The topic is the same as that in my previous posts: databases. Or, to be [...]]]></description>
			<content:encoded><![CDATA[<p>In some of my previous posts, I&#8217;ve pretty much ranted about the poor design qualities of some people that enjoy calling themselves PHP programmers. In these two posts however, I&#8217;d like to show you what good and proper design is. The topic is the same as that in my previous posts: databases. Or, to be more precise, <em>database abstraction.</em></p>
<p>In <a title="Applied design patterns: Database abstraction (Part 1)" href="http://greatjustice.info/applied-design-patterns-database-abstraction-part-1/" target="_self">the first part</a>, transformed a concrete set of database interaction classes into an abstract set, to improve flexibility and extensibility. In the second part (i.e. this one), we&#8217;ll introduce a design pattern which will help us to manage and maintain the new abstract database classes and their concrete implementations. In this post, we&#8217;ll create and implement the design pattern we&#8217;ll use to determine which concrete database connection should be used, using an implementation of the Factory Method.</p>
<p><span id="more-20"></span></p>
<p>In <a title="Applied design patterns: Database abstraction (Part 1)" href="http://greatjustice.info/applied-design-patterns-database-abstraction-part-1/" target="_self">the first part</a>, we encountered the following line in the example code:</p>
<pre name="code" class="php">$databaseConnection = new MySQLDatabaseConnection($server, $username, $password);</pre>
<p>This, in itself, will work, but it&#8217;s not what we want. If we used this line in every bit of code where we require a database connection, our application would become dependent on the MySQLDatabaseConnection class. Not only that, but it&#8217;ll become rigid, inflexible, and a general pain in the arse to maintain. You might consider that in most cases your application will stick to a single database, but what if  you&#8217;re writing an application for clients that may want to use a different database? Do you just lock them out saying &#8216;No we don&#8217;t support &#8216;? Not only that, but learning this method now (and not even particularly for this situation) will give you a benefit in the future, when you encounter similar problems. Anyways, back to the tutorial.</p>
<p>In order to solve the above case of inflexibility, we&#8217;ll want to move the concrete object instantiation (= object creation) to a single location. We&#8217;ll want to be able to create an object that can produce new instances of the objects required to work with a database of a specific type, and pass that object around to the bits of code that need it. The $databaseConnection in the above example will, as such, be instantiated not by calling the new operator on a specific database connection type, but by calling a method on an object that&#8217;s assigned to the part of the program using databases which will return an instance of the database connection type currently in use. The former sentence is complex, but I hope it&#8217;ll make sense in a short while. Read on.</p>
<p>To do the above, we have to create ourselves a Factory Method. The name &#8220;Factory Method&#8221; refers to a Design Pattern, an element of reusable object-oriented software as described in The book on Design Patterns, and probably in a load of other books as well. This method (or function, whatever floats your boat) will return an instance of the DatabaseConnection currently used in your application.</p>
<p>Next to a method that creates / returns a DatabaseConnection, we&#8217;ll also want to support connection re-use: in most applications, people only want a single database connection at a time for the duration of a request, so we&#8217;ll want to make the behavior of the factory as such that it&#8217;ll only create a new instance of a Connection if it isn&#8217;t already there. This only-one-object-of-a-certain-type-at-a-time business can be achieved by using the Singleton pattern (albeit slightly different from the one described in The Book, but that difference isn&#8217;t important).</p>
<p>In our Factory, we&#8217;ll also want to keep track of all existing connections, so we&#8217;ll have to maintain a list of active database connections and the means to manage them.</p>
<p>We&#8217;ll create a new interface for this, the ConnectionManager. The ConnectionManager is in essence a pretty basic class, in that it contains only one field (an array that contains the currently active connections) and a handful of connection management methods - one for establishing a connection, one for closing a connection, one for getting a connection from the list of connections, and one for creating a new connection. We&#8217;ll want the ConnectionManager to create new Connections based on whichever type of database is currently selected. To do this, we&#8217;ll create one ConnectionManager for each type of database, so that a MySQLConnectionManager returns MySQLConnections, and a PostgreSQLConnectionManager returns PostgreSQLConnections.</p>
<p>There is one thing that&#8217;s shared in all ConnectionManagers by the way, and that&#8217;s that they all contain a list of database connections. We&#8217;ll take advantage of PHP&#8217;s typelessness by defining 