<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>W-Shadow.com &#187; Programming</title>
	<atom:link href="http://w-shadow.com/blog/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://w-shadow.com</link>
	<description>Slightly Advanced Computer Stuff (and some magic)</description>
	<lastBuildDate>Fri, 20 Nov 2009 16:32:59 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>How To Extract HTML Tags And Their Attributes With PHP</title>
		<link>http://w-shadow.com/blog/2009/10/20/how-to-extract-html-tags-and-their-attributes-with-php/</link>
		<comments>http://w-shadow.com/blog/2009/10/20/how-to-extract-html-tags-and-their-attributes-with-php/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 14:35:03 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[data mining]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[extract attributes]]></category>
		<category><![CDATA[extract tags]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP script]]></category>
		<category><![CDATA[regular expressions]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1375</guid>
		<description><![CDATA[There are several ways to extract specific tags from an HTML document. The one that most people will think of first is probably regular expressions. However, this is not always &#8211; or, as some would insist, ever &#8211; the best approach. Regular expressions can be handy for small hacks, but using a real HTML parser [...]]]></description>
			<content:encoded><![CDATA[<p>There are several ways to extract specific tags from an HTML document. The one that most people will think of first is probably regular expressions. However, this is not always &#8211; or, as some would insist, <em>ever</em> &#8211; the best approach. Regular expressions can be handy for small hacks, but using a real HTML parser will usually lead to simpler and more robust code. Complex queries, like &#8220;find all rows with the class .foo of the second table of this document and return all links contained in those rows&#8221;, can also be done much easier with a decent parser.</p>
<p>There are <em>some</em> (though very few they may be) edge case where regular expressions might work better, so I will discuss both approaches in this post.</p>
<h3>Extracting Tags With DOM</h3>
<p>PHP 5 comes with a usable <a href="http://php.net/manual/en/book.dom.php">DOM API</a> built-in that you can use to parse and manipulate (X)HTML documents. For example, here&#8217;s how you could use it to extract all link URLs from a HTML file :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Load the HTML page</span>
<span style="color: #000088;">$html</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page.htm'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//Create a new DOM document</span>
<span style="color: #000088;">$dom</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMDocument<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Parse the HTML. The @ is used to suppress any parsing errors</span>
<span style="color: #666666; font-style: italic;">//that will be thrown if the $html string isn't valid XHTML.</span>
<span style="color: #339933;">@</span><span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadHTML</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$html</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Get all links. You could also use any other tag name here,</span>
<span style="color: #666666; font-style: italic;">//like 'img' or 'table', to extract other tags.</span>
<span style="color: #000088;">$links</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'a'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Iterate over the extracted links and display their URLs</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$links</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">//Extract and show the &quot;href&quot; attribute. </span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$link</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'href'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In addition to <code>getElementsByTagName()</code> you can also use <code>$dom-&gt;getElementById()</code> to find tags with a specific id. For more complex tasks, like extracting deeply nested tags, <a href="http://www.php.net/manual/en/class.domxpath.php">XPath</a> is probably the way to go. For example, to find all list items with the class &#8220;foo&#8221; containing links with the class &#8220;bar&#8221; and display the link URLs :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Load the HTML page</span>
<span style="color: #000088;">$html</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page.htm'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//Parse it. Here we use loadHTML as a static method</span>
<span style="color: #666666; font-style: italic;">//to parse the HTML and create the DOM object in one go.</span>
<span style="color: #339933;">@</span><span style="color: #000088;">$dom</span> <span style="color: #339933;">=</span> DOMDocument<span style="color: #339933;">::</span><span style="color: #004000;">loadHTML</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$html</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Init the XPath object</span>
<span style="color: #000088;">$xpath</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMXpath<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dom</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Query the DOM</span>
<span style="color: #000088;">$links</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$xpath</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'//li[contains(@class, &quot;foo&quot;)]//a[@class = &quot;bar&quot;]'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Display the results as in the previous example</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$links</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$link</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'href'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>For more information about DOM and XPath see these resources : </p>
<ul>
<li><a href="http://www.php.net/manual/en/book.dom.php">DOM API documentation</a></li>
<li><a href="http://www.w3schools.com/Xpath/">W3Schools XPath tutorial</a></li>
<li><a href="http://www.w3.org/TR/xpath">XPath language specification</a></li>
</ul>
<p>Honourable mention : <a href="http://simplehtmldom.sourceforge.net/">Simple HTML DOM Parser</a> is a popular alternative HTML parser for PHP 5 that lets you manipulate HTML pages with jQuery-like ease. However, I personally wouldn&#8217;t recommend using it if you care about your script&#8217;s performance, as in my tests Simple HTML DOM was about 30 times slower than DOMDocument.</p>
<h3>Extracting Tags &#038; Attributes With Regular Expressions</h3>
<p>There are only two advantages to processing HTML with regular expressions &#8211; availability and edge-case performance. While most parsers require PHP 5 or later, regular expressions are available pretty much anywhere. Also, they are a little bit faster than real parsers when you need to extract something from a <em>very</em> large document (on the order of 400 KB or more). Still, in most cases you&#8217;re better off using the PHP DOM extension or even Simple HTML DOM, not messing with convoluted regexps.</p>
<p>That said, here&#8217;s a PHP function that can extract any HTML tags and their attributes from a given string :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * extract_tags()
 * Extract specific HTML tags and their attributes from a string.
 *
 * You can either specify one tag, an array of tag names, or a regular expression that matches the tag name(s). 
 * If multiple tags are specified you must also set the $selfclosing parameter and it must be the same for 
 * all specified tags (so you can't extract both normal and self-closing tags in one go).
 * 
 * The function returns a numerically indexed array of extracted tags. Each entry is an associative array
 * with these keys :
 * 	tag_name	- the name of the extracted tag, e.g. &quot;a&quot; or &quot;img&quot;.
 *	offset		- the numberic offset of the first character of the tag within the HTML source.
 *	contents	- the inner HTML of the tag. This is always empty for self-closing tags.
 *	attributes	- a name -&gt; value array of the tag's attributes, or an empty array if the tag has none.
 *	full_tag	- the entire matched tag, e.g. '&lt;a href=&quot;http://example.com&quot;&gt;example.com&lt;/a&gt;'. This key 
 *		          will only be present if you set $return_the_entire_tag to true.	   
 *
 * @param string $html The HTML code to search for tags.
 * @param string|array $tag The tag(s) to extract.							 
 * @param bool $selfclosing	Whether the tag is self-closing or not. Setting it to null will force the script to try and make an educated guess. 
 * @param bool $return_the_entire_tag Return the entire matched tag in 'full_tag' key of the results array.  
 * @param string $charset The character set of the HTML code. Defaults to ISO-8859-1.
 *
 * @return array An array of extracted tags, or an empty array if no matching tags were found. 
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> extract_tags<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tag</span><span style="color: #339933;">,</span> <span style="color: #000088;">$selfclosing</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$return_the_entire_tag</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #000088;">$charset</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'ISO-8859-1'</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tag</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$tag</span> <span style="color: #339933;">=</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'|'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tag</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//If the user didn't specify if $tag is a self-closing tag we try to auto-detect it</span>
	<span style="color: #666666; font-style: italic;">//by checking against a list of known self-closing tags.</span>
	<span style="color: #000088;">$selfclosing_tags</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'area'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'base'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'basefont'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'br'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'hr'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'input'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'img'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'link'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'meta'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'col'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'param'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">is_null</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$selfclosing</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$selfclosing</span> <span style="color: #339933;">=</span> <span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$tag</span><span style="color: #339933;">,</span> <span style="color: #000088;">$selfclosing_tags</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//The regexp is different for normal and self-closing tags because I can't figure out </span>
	<span style="color: #666666; font-style: italic;">//how to make a sufficiently robust unified one.</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$selfclosing</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$tag_pattern</span> <span style="color: #339933;">=</span> 
			<span style="color: #0000ff;">'@&lt;(?P&lt;tag&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$tag</span><span style="color: #339933;">.</span><span style="color: #0000ff;">')			# &lt;tag
			(?P&lt;attributes&gt;\s[^&gt;]+)?		# attributes, if any
			\s*/?&gt;					# /&gt; or just &gt;, being lenient here 
			@xsi'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$tag_pattern</span> <span style="color: #339933;">=</span> 
			<span style="color: #0000ff;">'@&lt;(?P&lt;tag&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$tag</span><span style="color: #339933;">.</span><span style="color: #0000ff;">')			# &lt;tag
			(?P&lt;attributes&gt;\s[^&gt;]+)?		# attributes, if any
			\s*&gt;					# &gt;
			(?P&lt;contents&gt;.*?)			# tag contents
			&lt;/(?P=tag)&gt;				# the closing &lt;/tag&gt;
			@xsi'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000088;">$attribute_pattern</span> <span style="color: #339933;">=</span> 
		<span style="color: #0000ff;">'@
		(?P&lt;name&gt;\w+)							# attribute name
		\s*=\s*
		(
			(?P&lt;quote&gt;[\&quot;\'])(?P&lt;value_quoted&gt;.*?)(?P=quote)	# a quoted value
			|							# or
			(?P&lt;value_unquoted&gt;[^\s&quot;\']+?)(?:\s+|$)			# an unquoted value (terminated by whitespace or EOF) 
		)
		@xsi'</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//Find all tags </span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tag_pattern</span><span style="color: #339933;">,</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #339933;">,</span> PREG_SET_ORDER <span style="color: #339933;">|</span> PREG_OFFSET_CAPTURE <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">//Return an empty array if we didn't find anything</span>
		<span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000088;">$tags</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$matches</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$match</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">//Parse tag attributes, if any</span>
		<span style="color: #000088;">$attributes</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'attributes'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> 
&nbsp;
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$attribute_pattern</span><span style="color: #339933;">,</span> <span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'attributes'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$attribute_data</span><span style="color: #339933;">,</span> PREG_SET_ORDER <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
				<span style="color: #666666; font-style: italic;">//Turn the attribute data into a name-&gt;value array</span>
				<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$attribute_data</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$attr</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
					<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$attr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'value_quoted'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
						<span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$attr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'value_quoted'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$attr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'value_unquoted'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
						<span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$attr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'value_unquoted'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
						<span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span>
&nbsp;
					<span style="color: #666666; font-style: italic;">//Passing the value through html_entity_decode is handy when you want</span>
					<span style="color: #666666; font-style: italic;">//to extract link URLs or something like that. You might want to remove</span>
					<span style="color: #666666; font-style: italic;">//or modify this call if it doesn't fit your situation.</span>
					<span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #990000;">html_entity_decode</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">ENT_QUOTES</span><span style="color: #339933;">,</span> <span style="color: #000088;">$charset</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
					<span style="color: #000088;">$attributes</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$attr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000088;">$tag</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'tag_name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tag'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'offset'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> 
			<span style="color: #0000ff;">'contents'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'contents'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>?<span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'contents'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">:</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">//empty for self-closing tags</span>
			<span style="color: #0000ff;">'attributes'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$attributes</span><span style="color: #339933;">,</span> 
		<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$return_the_entire_tag</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$tag</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'full_tag'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> 			
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000088;">$tags</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$tag</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$tags</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>Usage examples</strong></p>
<p>Extract all links and output their URLs :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$html</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'example.html'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$nodes</span> <span style="color: #339933;">=</span> extract_tags<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'a'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$nodes</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'attributes'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'href'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Extract all heading tags and output their text :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$nodes</span> <span style="color: #339933;">=</span> extract_tags<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'h\d+'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$nodes</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$node</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #990000;">strip_tags</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$link</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'contents'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Extract meta tags :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$nodes</span> <span style="color: #339933;">=</span> extract_tags<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'meta'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Extract bold and italicised text fragments :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$nodes</span> <span style="color: #339933;">=</span> extract_tags<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'b'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'strong'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'em'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'i'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$nodes</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$node</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #990000;">strip_tags</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$node</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'contents'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The function is pretty well documented, so check the source if anything is unclear. Of course, you can also leave a comment if you have any further questions or feedback.</p>
<hr/>Copyright &copy; 2009 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/10/20/how-to-extract-html-tags-and-their-attributes-with-php/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>How To Make a &#8220;Falling Sand&#8221; Style Water Simulation</title>
		<link>http://w-shadow.com/blog/2009/09/29/falling-sand-style-water-simulation/</link>
		<comments>http://w-shadow.com/blog/2009/09/29/falling-sand-style-water-simulation/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 14:14:43 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[cellular automata]]></category>
		<category><![CDATA[falling sand game]]></category>
		<category><![CDATA[fluid simulation]]></category>
		<category><![CDATA[game design]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Processing]]></category>
		<category><![CDATA[simulation]]></category>
		<category><![CDATA[water simulation]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1295</guid>
		<description><![CDATA[Have you ever wondered how all those &#8220;falling sand&#8221; games work under the hood? If so, read on. Today I will discuss one of the possible ways how you could implement the &#8220;falling&#8221; part of the game &#8211; sand particles falling under the effects of gravity, water (or other liquids) flowing down a hillside, and [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever wondered how all those <a href="http://chir.ag/stuff/sand/">&#8220;falling sand&#8221; games</a> work under the hood? If so, read on. Today I will discuss one of the possible ways how you could implement the &#8220;falling&#8221; part of the game &#8211; sand particles falling under the effects of gravity, water (or other liquids) flowing down a hillside, and so on. <a href="http://w-shadow.com/files/FallingWater.zip">Source code</a> and a <a href="http://w-shadow.com/files/FallingSandWater/">live demo</a> are also available. This tutorial is along the same vein as my previous <a href="http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/">fluid simulation post</a> that dealt with pseudo-compressible fluids and pressure, but the specific algorithm is much simpler (and probably quite a bit faster, too).<em> </em></p>
<p><em>Side-note : No, I haven&#8217;t been completely consumed by an inexorable desire to build fun graphical toys instead of practically useful software, why do you ask? <img src='http://w-shadow.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  In fact, there&#8217;ll be some WordPress-related announcements later this week&#8230;</em></p>
<h3>Learning To <del datetime="2009-09-28T14:15:43+00:00">Fly</del> Fall</h3>
<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1299" title="Falling water movement" src="http://w-shadow.com/wp-content/uploads/2009/09/gravity-simulation-rules.png" alt="Falling water movement" width="120" height="236" />While I can&#8217;t claim intimate familiarity with the algorithms the aforementioned games use to simulate fire or explosions, it&#8217;s pretty easy to come up with a way to implement falling sand/flowing water. First, you need to figure out under what conditions something can fall/flow downwards. For a basic simulation this could be just a small set of very simple rules :</p>
<ul>
<li>For each entity that is affected by gravity
<ul>
<li>If there&#8217;s an empty space <strong>below</strong> it, move it <strong>down</strong>.</li>
<li>If there&#8217;s an empty space <strong>down and to the left</strong>, move it <strong>down and to the left</strong>.</li>
<li>If there&#8217;s an empty space <strong>down and to the right</strong>, move it <strong>down and to the right</strong>.</li>
</ul>
</li>
</ul>
<p>Next, you need to decide how to represent the simulation world and all the objects (like immovable walls, moving water particles <em>et cetera</em>) that it contains. One of the most common solutions is to use a two-dimensional array where each array element is an numeric ID of the material contained in that map tile. For example, 0 = air (or an empty square), 1 = wall, 2 = water, and so on.</p>
<p style="text-align: center;"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="size-full wp-image-1300 aligncenter" title="Map array" src="http://w-shadow.com/wp-content/uploads/2009/09/map-representation.png" alt="Map array" width="481" height="306" /></p>
<p>In most falling sand games each array element would correspond to a single pixel on the game&#8217;s screen. However, in my example application I used 20&#215;20 pixel tiles instead to make the underlying simulation behaviour easier to see.</p>
<p>If possible, use <em>byte</em> or <em>char</em> as the array element datatype. Using <em>int&#8217;s</em> might seem more straightforward, but it would also take up at least four times more memory and hurt performance. It&#8217;s also a good idea to make the array just a bit bigger than the actual map dimensions and create a single-tile &#8220;buffer zone&#8221; around the map so that you can avoid checking for boundary conditions during the simulation.</p>
<p>Finally, during the simulation step we just loop over the entire array and apply the simple rules I mentioned above to each tile that contains material that should be affected by gravity.</p>
<h3>Getting It Right</h3>
<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1301" title="Now that's just silly." src="http://w-shadow.com/wp-content/uploads/2009/09/whee.png" alt="Now that's just silly." width="78" height="211" />If you go ahead and implement the above algorithm as written, you will get a simulation that <em>kind-of</em> works, but quickly grinds to a halt on big maps and sometimes behaves in unexpected ways. For example, you might see sand tiles that seem to &#8220;teleport&#8221; to the bottom of the map instead of falling gradually and water that always flows <em>left</em> after hitting a free-standing ground tile (even though there&#8217;s a perfectly suitable channel available on the right side). Lets see what we can do about that.</p>
<p><strong>Keeping track of updated tiles</strong></p>
<p>The &#8220;teleportation&#8221; behaviour can happen if our simulation algorithm doesn&#8217;t keep track of which tiles it has already moved around during the current simulation step. For example, first it loops over the top row of the map, finds a water tile A and moves it downwards one row. Then it loops over the second row, finds the tile A, moves it again, goes to the third row, moves the same water tile <em>again</em>&#8230; and so on, until the water tile A hits a solid tile or falls off the map.</p>
<p>To prevent this bug we need to somehow remember which tiles have been updated already. Since I wanted to keep the memory use low, I used the most-significant bit of each map array element to indicate whether that tile was last updated on an even-numbered simulation step (0) or an odd-numbered step (1). Then, at the start of each step, the algorithm calculates what the flag should be for tiles updated in that step :</p>
<pre>update_mask = byte ( ( simulationFrameCount &amp; (long)1 ) &lt;&lt; 7 );
//this basically takes the modulo of frame-count / 2 and shifts the result 7 places to the left</pre>
<p>&#8230;then sets the msb of each tile it updates to that value and automatically skips tiles that have it already set to that value.</p>
<p><strong>Pseudo-random movement</strong></p>
<p>When a falling particle hits a free-standing fixed tile on a 2D map it has two choices &#8211; it can either move down and left, or down and right. In the naive algorithm I discussed above it will always try to move left first, leading to weirdness. Obviously we want it to choose at random, but on a big map generating a new random number for each tile would be slow. Instead, lets use the same approach as for the &#8220;teleportation&#8221; problem and move it either diagonally left if the current simulation step is even-numbered and or diagonally right if it&#8217;s odd-numbered. This can still introduce some artifacts in the simulation behaviour, but they&#8217;re rarer and and significantly less noticeable.</p>
<h3>Optimization</h3>
<p>Speaking of optimization, we don&#8217;t really need to update each gravity-enabled tile every time. Many of them will eventually end up in a situation where they can&#8217;t move anywhere (e.g. water at the bottom of a puddle or sand resting on a flat surface), so it would be nice if we could quickly skip them and not waste our time trying to apply the simulation rules to these static tiles. This would help performance quite a bit.</p>
<p>The way I implemented is with the help with another bit-flag. If the simulation algorithm discovers that it can&#8217;t move a tile in any direction, it will set the tile&#8217;s &#8220;static&#8221; bit-flag. It will also skip any tiles that have the &#8220;static&#8221; bit-flag set.</p>
<p>There&#8217;s some additional book-keeping we need to do to make this work as intended. When an empty space is created somewhere in the map (e.g. by a water tile moving down) we need to re-activate any gravity-enabled tiles that are directly above the newly created hole, so that they can fall/flow down into that space.</p>
<h3>Possible Improvements</h3>
<p>The result is a pretty basic and plain simulation that is useful to explain the basic principle, but it wouldn&#8217;t really qualify as a full game. Here are some ideas you could use to improve it :</p>
<ul>
<li>Make water flow horizontally if there&#8217;s another water tile on top of it. Consider adding a simple pressure model [link to my prev. article].</li>
<li>Implement fluid density. This one is easy &#8211; if the current tile is more dense than the tile below it, swap them.</li>
<li>Add tile generators, e.g. a faucet that creates a water tile below itself on each simulation step (included in my demo application).</li>
<li>To improve performance, use a <a href="http://en.wikipedia.org/wiki/Quadtree">quadtree</a> to keep track of which regions of the map have interacting tiles and quickly skip inactive regions.</li>
<li>Explore the source code of existing games and look for interesting ideas. Some open-source examples : <a href="http://www.piettes.com/fallingsandgame/download.html">wxSand</a>, <a href="http://sourceforge.net/projects/sdlsand/">SDL Sand</a>.</li>
</ul>
<h3>Live Demo &amp; Source</h3>
<p>Like my previous <a href="http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/">fluid simulation app</a>, this one was also written in <a href="http://processing.org/">Processing</a>. In addition to a working implementation of the algorithm discussed above it also lets you draw and erase water/ground/faucet tiles using your mouse, pan around the map with the WASD keys, zoom in/out with the mouse wheel and more. However, be warned that the map rendering code is not very optimized so the simulation <em>will</em> degenerate into a slideshow if you zoom all the way out, regardless of how fast your system is.</p>
<ul>
<li><a href="http://w-shadow.com/files/FallingSandWater/">Live demo  (requires Java)</a></li>
<li><a href="http://w-shadow.com/files/FallingWater.zip">Source code</a></li>
</ul>
<hr/>Copyright &copy; 2009 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/09/29/falling-sand-style-water-simulation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Simple Fluid Simulation With Cellular Automata</title>
		<link>http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/</link>
		<comments>http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 19:48:33 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[cellular automata]]></category>
		<category><![CDATA[fluid dynamics]]></category>
		<category><![CDATA[fluid simulation]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Processing]]></category>
		<category><![CDATA[water dynamics]]></category>
		<category><![CDATA[water simulation]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1285</guid>
		<description><![CDATA[Last week I couldn&#8217;t use my regular dev. machine (broken graphics card), so all my WordPress-related plans were on hold. To pass the time, I built a simple water simulation in Processing. Today I&#8217;m going to show you this little application and explain how it works. Online demo and source code are included.
Big Words, or [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I couldn&#8217;t use my regular dev. machine (broken graphics card), so all my WordPress-related plans were on hold. To pass the time, I built a simple water simulation in <a href="http://processing.org/">Processing</a>. Today I&#8217;m going to show you this little application and explain how it works. Online demo and source code are included.</p>
<h3>Big Words, or The Theoretical Part</h3>
<p>Fluid dynamics is a complex topic. If you so much as <a rel="nofollow" href="http://en.wikipedia.org/wiki/Computational_fluid_dynamics">look it up in Wikipedia</a>, you will be immediately assaulted by integrals, differentials  and other agents of mathematical insanity. To accurately model a fluid you would need a quite an in-depth understanding of physics and calculus. And while that&#8217;s certainly not something one couldn&#8217;t figure out given enough time, &#8220;proper&#8221; fluid simulation is still extremely rare in non-academic applications and games because it&#8217;s <strong>slow</strong>.</p>
<p>One way to create a faster (though less accurate) simulation is by using <a rel="nofollow" href="http://en.wikipedia.org/wiki/Cellular_automata">cellular automata</a> to represent the water. A cellular automaton is basically a grid where each cell can be in one of a finite number of states, plus a set of rules that determine how a cell can change from one state to another. The rules are typically local &#8211; that is, they consider only the current cell and it&#8217;s direct neighbours when determining the new state. During each step of the simulation, you simply loop through the entire grid and apply the rules to each cell.</p>
<p>When simulating water or other fluids it can more appropriate to store a continuous value (e.g. water mass) in each cell, instead of using discrete states.</p>
<h3>CA-Based Water Simulation</h3>
<p>Before we go into details, lets take a look at the promised online demo. It will give you a good idea about what you can achieve with this approach :</p>
<p><a href="http://w-shadow.com/files/water_sim/"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-large wp-image-1291" title="Click to run the simulation" src="http://w-shadow.com/wp-content/uploads/2009/09/Water-Simulation1-490x513.png" alt="Click to run the simulation" width="490" height="513" /></a> <em>(klicken Sie auf das Bild; Java required)</em></p>
<p>Alright, on to the code stuff. Lets try simulating the most common fluid &#8211; water.</p>
<p><strong>The basic data structure</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Map dimensions</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> map_width <span style="color: #339933;">=</span> <span style="color: #cc66cc;">16</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> map_height <span style="color: #339933;">=</span> <span style="color: #cc66cc;">16</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Block types</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> AIR <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> GROUND <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> WATER <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Data structures</span>
<span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> blocks <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span>map_width<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>map_height<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">float</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> mass <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">float</span><span style="color: #009900;">&#91;</span>map_width<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>map_height<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span>,
          new_mass <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">float</span><span style="color: #009900;">&#91;</span>map_width<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>map_height<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></pre></div></div>

<p>I use two two-dimensional arrays to represent the simulation world. The <code>blocks</code> array defines a basic &#8220;map&#8221; where each cell can contain ground (solid, stops water flow), air (an empty cell, water can flow in) or water. Each water cell also has a corresponding entry in the <code>mass</code> array that defines how much water it contains. All water cells/blocks start out with one unit of water.</p>
<p>There&#8217;s also a third array &#8211; <code>new_mass</code> that is used to store intermediate mass values when running the simulation. Operating directly on the <code>mass</code> array is unadvisable because you would get various sideffects like water spreading at different speeds depending on the order in which you update the cells.</p>
<p><strong>Overall algorithm</strong></p>
<p>The main idea is to treat water as a slightly compressible liquid, as described in <a href="http://home.comcast.net/~tom_forsyth/papers/cellular_automata_for_physical_modelling.html">this article</a>. In terms of implementation, this means that if there are two or more water cells stacked vertically, the bottom cells will be able to hold slightly more water than normal. This way we don&#8217;t need to explicitly track pressure to make the water level equalize in communicating vessels &#8211; we can just look at how much excess water a cell has, and move it upwards if required.</p>
<p>Lets set up the exact fluid properties as constants :</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Water properties</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">float</span> MaxMass <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1.0</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//The normal, un-pressurized mass of a full water cell</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">float</span> MaxCompress <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0.02</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//How much excess water a cell can store, compared to the cell above it</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">float</span> MinMass <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0.0001</span><span style="color: #339933;">;</span>  <span style="color: #666666; font-style: italic;">//Ignore cells that are almost dry</span></pre></div></div>

<p>For example, if one cell contains 1.0 units of water, the cell below it should contain up to 1.02 units, the cell below that one should contain 1.04, the next one 1.06, and so on. There is one however special case that we need to consider to get a plausible simulation &#8211; what if the if the top cell contains less than <code>MaxMass</code> units of water? In my implementation the bottom cell will contain a proportionally smaller excess amount, not the usual <code>mass_of_the_cell_above + MaxCompression</code> units.</p>
<p>Based on the above, we can simulate water movement by looping over the <code>mass</code> array and applying these cellular automaton rules to each cell :</p>
<ol>
<li>Take the mass of the current cell and the cell <strong>below</strong> it and figure out how much water the bottom cell should contain. If it has less than that, remove the corresponding amount from the current cell and add it to the bottom cell.</li>
<li>Check the cell to the <strong>left</strong> of this one. If it has less water, move over enough water to make both cells contain the same amount.</li>
<li>Do the same thing for the <strong>right</strong> neighbour.</li>
<li>Do the same thing as in step 1., but for the cell <strong>above</strong> the current one.</li>
</ol>
<p>While doing this you also need to keep track of how much water the current cell still has remaining, or you could end up with negative-mass water blocks.</p>
<p>After the new mass of each cell has been calculated, you can safely copy over the new values to the <code>mass</code> array. You also need to update the <code>blocks</code> array so that cells that are now dry get marked as empty and vice versa.</p>
<p>Here&#8217;s the simulation code :</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">void</span> simulate_compression<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">float</span> Flow <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">float</span> remaining_mass<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">//Calculate and apply flow for each block</span>
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> x <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> x <span style="color: #339933;">&lt;=</span> map_width<span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
     <span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> y <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> y <span style="color: #339933;">&lt;=</span> map_height<span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
       <span style="color: #666666; font-style: italic;">//Skip inert ground blocks</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> GROUND<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//Custom push-only flow</span>
       Flow <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
       remaining_mass <span style="color: #339933;">=</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//The block below this one</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span>blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> GROUND<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
         Flow <span style="color: #339933;">=</span> get_stable_state_b<span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">+</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> Flow <span style="color: #339933;">&gt;</span> MinFlow <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
           Flow <span style="color: #339933;">*=</span> <span style="color: #cc66cc;">0.5</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//leads to smoother flow</span>
         <span style="color: #009900;">&#125;</span>
         Flow <span style="color: #339933;">=</span> constrain<span style="color: #009900;">&#40;</span> Flow, <span style="color: #cc66cc;">0</span>, min<span style="color: #009900;">&#40;</span>MaxSpeed, remaining_mass<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+=</span> Flow<span style="color: #339933;">;</span>   
         remaining_mass <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span>
&nbsp;
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//Left</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> blocks<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> GROUND <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">//Equalize the amount of water in this block and it's neighbour</span>
         Flow <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">4</span><span style="color: #339933;">;</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> Flow <span style="color: #339933;">&gt;</span> MinFlow <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> Flow <span style="color: #339933;">*=</span> <span style="color: #cc66cc;">0.5</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
         Flow <span style="color: #339933;">=</span> constrain<span style="color: #009900;">&#40;</span>Flow, <span style="color: #cc66cc;">0</span>, remaining_mass<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">+=</span> Flow<span style="color: #339933;">;</span>
         remaining_mass <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span>
&nbsp;
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//Right</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> blocks<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> GROUND <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">//Equalize the amount of water in this block and it's neighbour</span>
         Flow <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">4</span><span style="color: #339933;">;</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> Flow <span style="color: #339933;">&gt;</span> MinFlow <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> Flow <span style="color: #339933;">*=</span> <span style="color: #cc66cc;">0.5</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
         Flow <span style="color: #339933;">=</span> constrain<span style="color: #009900;">&#40;</span>Flow, <span style="color: #cc66cc;">0</span>, remaining_mass<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">+=</span> Flow<span style="color: #339933;">;</span>
         remaining_mass <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span>
&nbsp;
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//Up. Only compressed water flows upwards.</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> GROUND <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
         Flow <span style="color: #339933;">=</span> remaining_mass <span style="color: #339933;">-</span> get_stable_state_b<span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">+</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> Flow <span style="color: #339933;">&gt;</span> MinFlow <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> Flow <span style="color: #339933;">*=</span> <span style="color: #cc66cc;">0.5</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
         Flow <span style="color: #339933;">=</span> constrain<span style="color: #009900;">&#40;</span> Flow, <span style="color: #cc66cc;">0</span>, min<span style="color: #009900;">&#40;</span>MaxSpeed, remaining_mass<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+=</span> Flow<span style="color: #339933;">;</span>   
         remaining_mass <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
     <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">//Copy the new mass values to the mass array</span>
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> x <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> x <span style="color: #339933;">&lt;</span> map_width <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> y <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> y <span style="color: #339933;">&lt;</span> map_height <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> x <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> x <span style="color: #339933;">&lt;=</span> map_width<span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
     <span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> y <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> y <span style="color: #339933;">&lt;=</span> map_height<span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
       <span style="color: #666666; font-style: italic;">//Skip ground blocks</span>
       <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> GROUND<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
       <span style="color: #666666; font-style: italic;">//Flag/unflag water blocks</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;</span> MinMass<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
         blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> WATER<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
         blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> AIR<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span>
     <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">//Remove any water that has left the map</span>
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> x <span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> x <span style="color: #339933;">&lt;</span> map_width<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>map_height<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> y <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> y <span style="color: #339933;">&lt;</span> map_height<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    mass<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    mass<span style="color: #009900;">&#91;</span>map_width<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>And here&#8217;s the function that calculates how to distribute a given amount of water between two vertically adjacent cells :</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Returns the amount of water that should be in the bottom cell.</span>
<span style="color: #000066; font-weight: bold;">float</span> get_stable_state_b <span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">float</span> total_mass <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> total_mass <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> total_mass <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">*</span>MaxMass <span style="color: #339933;">+</span> MaxCompress <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>MaxMass<span style="color: #339933;">*</span>MaxMass <span style="color: #339933;">+</span> total_mass<span style="color: #339933;">*</span>MaxCompress<span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span><span style="color: #009900;">&#40;</span>MaxMass <span style="color: #339933;">+</span> MaxCompress<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>total_mass <span style="color: #339933;">+</span> MaxCompress<span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>Full source code</strong></p>
<ul>
<li><a href="http://w-shadow.com/files/water_sim.zip"><strong>Download the source</strong></a> (23 KB)</li>
<li>You will need the Java-based <a href="http://processing.org/">Processing programming language</a> to run the code.</li>
</ul>
<p>I didn&#8217;t discuss how to render the water, or how to handle user interaction, but the source code also includes a simplistic implementation of those things.</p>
<h3>Conclusion</h3>
<p>CA-based algorithms have both advantages and disadvantages. On the one hand, they&#8217;re relatively fast and the simulation quality is often good enough for games and software toys. On the other, they can produce behaviour that is very unrealistic &#8211; for example, water falling into a basin will form a little &#8220;hill&#8221; and spread out slowly, instead of near-instantly as real water would. Whether this is an acceptable downside depends on your application.</p>
<p>For a different take on simulating fluid dynamics with cellular automata, check out this <a href="http://www.gamasutra.com/view/feature/3549/interview_the_making_of_dwarf_.php?page=9">interview with the author of Dwarf Fortress</a>.</p>
<hr/>Copyright &copy; 2009 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Changelog Generator For WordPress Plugins</title>
		<link>http://w-shadow.com/blog/2009/08/20/changelog-generator-for-wordpress-plugins/</link>
		<comments>http://w-shadow.com/blog/2009/08/20/changelog-generator-for-wordpress-plugins/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 19:25:55 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[changelog]]></category>
		<category><![CDATA[PHP script]]></category>
		<category><![CDATA[plugin directory]]></category>
		<category><![CDATA[repository]]></category>
		<category><![CDATA[SVN]]></category>
		<category><![CDATA[Trac]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress plugins]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1276</guid>
		<description><![CDATA[A few months ago, WordPress.org introduced a new feature available to plugins hosted in the Plugin Directory &#8211; changelogs. Having an easily accessible changelog is certainly a usability plus, but I felt it created unnecessary work for plugin developers. Personally, I usually provide meaningful log messages (example) when uploading a new version of a plugin [...]]]></description>
			<content:encoded><![CDATA[<p>A few months ago, WordPress.org introduced a new feature available to plugins hosted in the Plugin Directory &#8211; <a href="http://westi.wordpress.com/2009/06/20/changelogs-changelogs-changelogs/">changelogs</a><span>. Having an easily accessible changelog is certainly a usability plus, but I felt it created unnecessary work for plugin developers. Personally, I usually provide meaningful log messages (</span><a href="http://plugins.trac.wordpress.org/log/broken-link-checker">example</a><span>) when uploading a new version of a plugin to the repository, so updating the changelog with pretty much the same information seems redundant.</span></p>
<p><span>This gave me the idea to write a PHP script that can generate a wordpress.org-compatible changelog from the revision log. It works for any plugin hosted in the official plugins directory and <span class="hiddenGrammarError">can be</span> a handy starting point for adding a changelog to plugins that don&#8217;t have it yet :</span></p>
<ul>
<li><strong><a href="http://w-shadow.com/wpchangelog/"><span>Run the changelog generator</span></a></strong></li>
<li><a href="http://w-shadow.com/files/wpchangelog.zip">Download the source code</a> (97 KB, requires PHP 5)</li>
</ul>
<p>For those too lazy to click one of the above links, here&#8217;s a screenshot :</p>
<p><a href="http://w-shadow.com/wpchangelog/"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-1278" title="Changelog generator for WordPress plugins" src="http://w-shadow.com/wp-content/uploads/2009/08/Changelog-Generator.png" alt="Changelog generator for WordPress plugins" width="490" height="205" /></a></p>
<p>And I really do need to stop making these small hacks <img src='http://w-shadow.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<hr/>Copyright &copy; 2009 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/08/20/changelog-generator-for-wordpress-plugins/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How To Speed Up Your JavaScript (Video)</title>
		<link>http://w-shadow.com/blog/2009/08/10/how-to-speed-up-your-javascript-video/</link>
		<comments>http://w-shadow.com/blog/2009/08/10/how-to-speed-up-your-javascript-video/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 15:52:51 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google TechTalks]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[web apps]]></category>
		<category><![CDATA[youtube videos]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1251</guid>
		<description><![CDATA[JavaScript has become an integral part of the modern Web. Some would praise it as the miracle stuff that ties together diverse web technologies and creates more responsive user interfaces, the stuff that makes glorious mashups and truly interactive web apps possible. Some would rather liken it to a sticky sludge that attaches itself to [...]]]></description>
			<content:encoded><![CDATA[<p>JavaScript has become an integral part of the modern Web. Some would praise it as the miracle stuff that ties together diverse web technologies and creates more responsive user interfaces, the stuff that makes glorious mashups and truly interactive web apps possible. Some would rather liken it to a sticky sludge that attaches itself to a perfectly good (X)HTML site and transmogrifies it into a hulking mass of slowness.</p>
<p>Here&#8217;s a <a href="http://www.youtube.com/watch?v=mHtdZgou0qU">very interesting video</a> from <a href="http://www.youtube.com/user/googletechtalks">Google TechTalks</a> that discusses a number of advanced JS optimization techniques that will help your site avoid that horrible fate :</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/mHtdZgou0qU&#038;hl=en&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/mHtdZgou0qU&#038;hl=en&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p><strong>Bonus :</strong> If you&#8217;re a WordPress dev and intend to use the bundled jQuery library, check out these <a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx">25 tips for improving your jQuery usage</a>. This is one of the most comprehensive jQuery tip sheets I&#8217;ve seen.</p>
<p><strong>Also :</strong> <a href="http://www.nihilogic.dk/labs/wolf/">Wolfenstein 3D implemented in JavaScript</a> <img src='http://w-shadow.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<hr/>Copyright &copy; 2009 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/08/10/how-to-speed-up-your-javascript-video/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calculating Readability Metrics In PHP</title>
		<link>http://w-shadow.com/blog/2009/04/28/calculating-readability-metrics-in-php/</link>
		<comments>http://w-shadow.com/blog/2009/04/28/calculating-readability-metrics-in-php/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 17:40:34 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[english language]]></category>
		<category><![CDATA[flesch kincaid grade level]]></category>
		<category><![CDATA[gunning fog index]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[readability]]></category>
		<category><![CDATA[readability formulas]]></category>
		<category><![CDATA[readability metrics]]></category>
		<category><![CDATA[readability tests]]></category>
		<category><![CDATA[smog index]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1081</guid>
		<description><![CDATA[Readability metrics, also known as readability formulas, are a set of algorithms that estimate the readability of text. Most tests are fairly primitive as they only take into account things like sentence length and the average number of syllables per word, but ignore deeper factors like sentence structure and semantics.
Still, readability metrics can be useful [...]]]></description>
			<content:encoded><![CDATA[<p><img style=' float: left; padding: 4px; margin: 0 7px 2px 0;'  src="http://w-shadow.com/wp-content/uploads/2009/04/lorem-ipsum.png" alt="Lorem Ipsum" title="Too much XKCD" width="190" height="156" class="alignleft size-full wp-image-1086" />Readability metrics, also known as readability formulas, are a set of algorithms that estimate the readability of text. Most tests are fairly primitive as they only take into account things like sentence length and the average number of syllables per word, but ignore deeper factors like sentence structure and semantics.</p>
<p>Still, readability metrics can be useful as a rough indicator of how understandable your writing is. Other possible uses include detecting smart-ass comments and even catching spam (obviously, most spam messages would score very low on a readability test).</p>
<p>If you want to do something like that in your own PHP application(s), take a look at <a href="http://code.google.com/p/php-text-statistics/">PHP Text Statistics</a>. It&#8217;s a PHP class that implements a number of readability tests, including : </p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Flesch-Kincaid_Readability_Test" rel="nofollow">Flesch-Kincaid Reading Ease</a> (probably the most popular metric)</li>
<li><a href="http://en.wikipedia.org/wiki/Flesch-Kincaid_Readability_Test#Flesch.E2.80.93Kincaid_Grade_Level" rel="nofollow">Flesch-Kincaid Grade Level</a></li>
<li><a href="http://en.wikipedia.org/wiki/Gunning-Fog_Index" rel="nofollow">Gunning-Fog Index</a></li>
<li><a href="http://en.wikipedia.org/wiki/Coleman-Liau_Index" rel="nofollow">Coleman-Liau Index</a></li>
<li><a href="http://en.wikipedia.org/wiki/SMOG_(Simple_Measure_Of_Gobbledygook)" rel="nofollow">SMOG index</a></li>
<li><a href="http://en.wikipedia.org/wiki/Automated_Readability_Index" rel="nofollow">Automated Reability Index</a></li>
</ul>
<p>It can also calculate other metrics like sentence count, syllable count, average words per sentence, and so on. </p>
<p>The class is very easy to use &#8211; just <code>include</code> one file, create an instance, and call one of the suggestively named methods. There&#8217;s not much &#8220;official&#8221; documentation but the source code is well-commented and easy to understand. </p>
<p>The only flaw that stuck out to me was how inefficient the script can be. You probably won&#8217;t notice it unless you need to analyze huge volumes of text, but it could really use some optimization. In fact, I managed to improve the performance by ~30% simply by eliminating a few redundant function calls (you can <a href="http://w-shadow.com/files/TextStatistics.rar">download the modified version here</a> if you&#8217;re interested).</p>
<p>Ah well, it&#8217;s a useful class overall. I&#8217;m sure it will come in handy the occasional NLP exploit or <a href="http://twanalyst.com/">mashup</a>. </p>
<p><em>Hmm, this gives me an idea for a WordPress plugin&#8230;.</em></p>
<hr/>Copyright &copy; 2009 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/04/28/calculating-readability-metrics-in-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How To Get Per-Core CPU Usage</title>
		<link>http://w-shadow.com/blog/2009/04/17/per-core-cpu-usage/</link>
		<comments>http://w-shadow.com/blog/2009/04/17/per-core-cpu-usage/#comments</comments>
		<pubDate>Fri, 17 Apr 2009 17:22:48 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[CPU usage]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[downloads]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[multicore]]></category>
		<category><![CDATA[Windows API]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1058</guid>
		<description><![CDATA[It&#8217;s pretty easy to get the average CPU usage, but how about calculating the per-code load on multicore systems? Turns out it&#8217;s also simple enough if you use performance counters. 
Windows API includes a subset of functions that provide various performance-related information, which includes data on how busy individual processors or cores are. In this [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s pretty easy to <a href="http://www.codeproject.com/KB/threads/Get_CPU_Usage.aspx">get the average CPU usage</a>, but how about calculating the per-code load on multicore systems? Turns out it&#8217;s also simple enough if you use <a href="http://msdn.microsoft.com/en-us/library/aa373083(VS.85).aspx">performance counters</a>. </p>
<p>Windows API includes a subset of functions that provide various performance-related information, which includes data on how busy individual processors or cores are. In this post I&#8217;ll show you how to retrieve and use this information. I&#8217;ve also included a simple example application that demonstrates the functionality (the download link is at the end of the post) :</p>
<div id="attachment_1061" class="wp-caption aligncenter" style="width: 342px;  border: 1px solid #dddddd; background-color: #f3f3f3; padding-top: 4px; margin: 10px; text-align:center; display: block; margin-right: auto; margin-left: auto;"><img src="http://w-shadow.com/wp-content/uploads/2009/04/per-core-cpu-usage-screenshot.png" alt="Screenshot of the example application" title="Screenshot of the example application" width="332" height="130" class="size-full wp-image-1061" /><p style=' padding: 0 4px 5px; margin: 0;'  class="wp-caption-text">Screenshot of the example application</p></div>
<p>The example app was written in Delphi, but the salient parts are almost purely Windows API so they should be easy to translate to other programming languages.</p>
<h3>Algorithm Overview</h3>
<p>Here&#8217;s a general overview of how to use the performance counter API to get the per-core usage numbers.</p>
<p><strong>Initialization</strong></p>
<ol>
<li>Create a performance query using <a href="http://msdn.microsoft.com/en-us/library/aa372652(VS.85).aspx">PdhOpenQuery</a>.</li>
<li>Generate a list of performance counter paths (one for each CPU or core) by feeding a wildcard path to PdhExpandWildCardPath. In this case, this is the path that we need :<br />
<code>\Processor(*/*#*)\% Processor Time</code><br />
You can read more about counter path syntax <a href="http://msdn.microsoft.com/en-us/library/aa373193(VS.85).aspx">here</a>.</p>
<p><em>Note : Unfortunately, the API makes no distinction between multiple physical processors and multiple cores, so you will get a &#8220;&#8230;\Processor(X)\&#8230;&#8221; entry for each core.</em></li>
<li>Add the generated counter paths to the query using <a href="http://msdn.microsoft.com/en-us/library/aa372204(VS.85).aspx">PdhAddCounter</a> and save the returned handle(s) for later.</li>
</ol>
<p><strong>Collecting &#038; Displaying Data</strong><br />
CPU usage is typically measured over an interval of time, so you will need to collect at least two data samples at different times to get a meaningful result. Depending on your needs, you could either : </p>
<ul>
<li>Collect one sample, sleep() for a second, collect another sample and calculate the result; <strong>OR</strong></li>
<li>Set up a timer or a loop to calculate &#038; displays the CPU usage periodically. That&#8217;s what I&#8217;ll do in this tutorial.</li>
</ul>
<p>Regardless of whether you only need a one-time measurement or periodic updates, the process is very similar API-wise. First, call <a href="http://msdn.microsoft.com/en-us/library/aa372563(VS.85).aspx">PdhCollectQueryData</a> to update all counters associated with the query. Then call <a href="http://msdn.microsoft.com/en-us/library/aa372637(VS.85).aspx">PdhGetFormattedCounterValue</a> with each counter handle to get the actual data. If you set the output format flag to PDH_FMT_DOUBLE the function will give you the CPU/core load percentage as a floating-point value in the range of [0..100]. </p>
<p>If you need periodic updates just call these two functions repeatedly.</p>
<p><strong>Cleanup</strong><br />
When you&#8217;re done, call <a href="http://msdn.microsoft.com/en-us/library/aa372558(VS.85).aspx">PdhCloseQuery</a> to close counters associated with the query and free up allocated system resources. You don&#8217;t need to explicitly remove individual counters.</p>
<h3>Source</h3>
<p>This is the source code of a simple Delphi 2009 application that displays the load percentage of each processor core in a progress bar. The output is updated every second by using a timer component.</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">unit</span> CoreUsage<span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">interface</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">uses</span>
  Windows<span style="color: #000066;">,</span> Messages<span style="color: #000066;">,</span> SysUtils<span style="color: #000066;">,</span> Variants<span style="color: #000066;">,</span> Classes<span style="color: #000066;">,</span> Graphics<span style="color: #000066;">,</span> Controls<span style="color: #000066;">,</span> Forms<span style="color: #000066;">,</span>
  Dialogs<span style="color: #000066;">,</span> StdCtrls<span style="color: #000066;">,</span> JwaWindows<span style="color: #000066;">,</span> ExtCtrls<span style="color: #000066;">,</span> ComCtrls<span style="color: #000066;">,</span> Gauges<span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">type</span>
  TForm1 <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">class</span><span style="color: #000066;">&#40;</span>TForm<span style="color: #000066;">&#41;</span>
    Timer1<span style="color: #000066;">:</span> TTimer<span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">procedure</span> FormCreate<span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">procedure</span> Timer1Timer<span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">procedure</span> FormDestroy<span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span>
    <span style="color: #808080; font-style: italic;">{ Private declarations }</span>
  <span style="color: #000000; font-weight: bold;">public</span>
    <span style="color: #808080; font-style: italic;">{ Public declarations }</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
  TCounter <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">record</span>
   Path <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
   Handle <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>
   mLabel <span style="color: #000066;">:</span> TLabel<span style="color: #000066;">;</span>
   mGauge <span style="color: #000066;">:</span> TGauge<span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">var</span>
  Form1<span style="color: #000066;">:</span> TForm1<span style="color: #000066;">;</span>
  Counters <span style="color: #000066;">:</span> <span style="color: #000000; font-weight: bold;">array</span> <span style="color: #000000; font-weight: bold;">of</span> TCounter<span style="color: #000066;">;</span>
  Query <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Cardinal</span> <span style="color: #000066;">=</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">implementation</span>
&nbsp;
<span style="color: #008000; font-style: italic;">{$R *.dfm}</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> TForm1<span style="color: #000066;">.</span><span style="color: #006600;">FormCreate</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
 dwSize<span style="color: #000066;">,</span> h <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>
 cnt<span style="color: #000066;">,</span> i <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
 pPaths<span style="color: #000066;">:</span><span style="color: #000066; font-weight: bold;">PWideChar</span><span style="color: #000066;">;</span>
 pIterator<span style="color: #000066;">:</span><span style="color: #000066; font-weight: bold;">PwideChar</span><span style="color: #000066;">;</span>
 InstanceId<span style="color: #000066;">,</span> CounterPath <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
 status <span style="color: #000066;">:</span> PDH_STATUS<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #808080; font-style: italic;">//Create a performance query</span>
  <span style="color: #000000; font-weight: bold;">if</span>  PdhOpenQuery<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">,</span> Query<span style="color: #000066;">&#41;</span> <span style="color: #000066;">=</span> ERROR_SUCCESS <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">begin</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">//Get all valid processor/core usage counter paths by expanding</span>
    <span style="color: #808080; font-style: italic;">//a wildcard path. To do this, we must first call PdhExpandWildCardPath</span>
    <span style="color: #808080; font-style: italic;">//with buffer size set to zero to get the actual required buffer size.</span>
    dwSize <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">;</span>
    pPaths <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">;</span>
&nbsp;
    status <span style="color: #000066;">:</span><span style="color: #000066;">=</span> PdhExpandWildCardPath<span style="color: #000066;">&#40;</span>
      <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">,</span>                                  <span style="color: #808080; font-style: italic;">//search the local computer</span>
      <span style="color: #ff0000;">'\Processor(*/*#*)\% Processor Time'</span><span style="color: #000066;">,</span> <span style="color: #808080; font-style: italic;">//we want CPU usage counters for all CPUs/cores</span>
      pPaths<span style="color: #000066;">,</span>                               <span style="color: #808080; font-style: italic;">//user-allocated buffer; currently null</span>
      dwSize<span style="color: #000066;">,</span>                               <span style="color: #808080; font-style: italic;">//buffer size</span>
      <span style="color: #0000ff;">0</span><span style="color: #000066;">&#41;</span> <span style="color: #000066;">;</span>                                  <span style="color: #808080; font-style: italic;">//no flags</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">if</span> status <span style="color: #000066;">=</span> PDH_MORE_DATA <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">begin</span>
      dwSize <span style="color: #000066;">:</span><span style="color: #000066;">=</span> dwSize <span style="color: #000066;">+</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">;</span> <span style="color: #808080; font-style: italic;">//+1 byte required in XP and below.</span>
      pPaths <span style="color: #000066;">:</span><span style="color: #000066;">=</span> GetMemory<span style="color: #000066;">&#40;</span>dwSize<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> <span style="color: #808080; font-style: italic;">//Allocate an output buffer.</span>
&nbsp;
      <span style="color: #808080; font-style: italic;">//Really get the counter paths.</span>
      status <span style="color: #000066;">:</span><span style="color: #000066;">=</span> PdhExpandWildCardPath<span style="color: #000066;">&#40;</span>
        <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">,</span>
        <span style="color: #ff0000;">'\Processor(*/*#*)\% Processor Time'</span><span style="color: #000066;">,</span>
        pPaths<span style="color: #000066;">,</span>
        dwSize<span style="color: #000066;">,</span>
        <span style="color: #0000ff;">0</span><span style="color: #000066;">&#41;</span> <span style="color: #000066;">;</span>
&nbsp;
      <span style="color: #000000; font-weight: bold;">if</span> status <span style="color: #000066;">=</span> ERROR_SUCCESS <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">begin</span>
&nbsp;
        cnt <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">;</span>
        <span style="color: #000066;">SetLength</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">,</span> <span style="color: #0000ff;">32</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;">//PdhExpandWildCardPath returns the counter list (pPaths) as an array</span>
        <span style="color: #808080; font-style: italic;">//of null-terminated strings where the last item is a zero-length</span>
        <span style="color: #808080; font-style: italic;">//string (i.e. just #0). We'll now iterate over this list with some</span>
        <span style="color: #808080; font-style: italic;">//simple pointer math.</span>
        pIterator <span style="color: #000066;">:</span><span style="color: #000066;">=</span> pPaths<span style="color: #000066;">;</span>
        <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #000066;">&#40;</span><span style="color: #000066;">strlen</span><span style="color: #000066;">&#40;</span>pIterator<span style="color: #000066;">&#41;</span>&gt;<span style="color: #0000ff;">0</span><span style="color: #000066;">&#41;</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
&nbsp;
          CounterPath <span style="color: #000066;">:</span><span style="color: #000066;">=</span> pIterator<span style="color: #000066;">;</span>
          pIterator <span style="color: #000066;">:</span><span style="color: #000066;">=</span> pIterator <span style="color: #000066;">+</span> <span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>pIterator<span style="color: #000066;">&#41;</span> <span style="color: #000066;">+</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">;</span>
&nbsp;
          <span style="color: #808080; font-style: italic;">//Find the counter instance ID (the part in parentheses)</span>
          i <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">Pos</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'('</span><span style="color: #000066;">,</span> CounterPath<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
          InstanceId <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">Copy</span><span style="color: #000066;">&#40;</span>CounterPath<span style="color: #000066;">,</span> i<span style="color: #000066;">+</span><span style="color: #0000ff;">1</span><span style="color: #000066;">,</span> <span style="color: #000066;">Pos</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">')'</span><span style="color: #000066;">,</span> CounterPath<span style="color: #000066;">&#41;</span><span style="color: #000066;">-</span>i<span style="color: #000066;">-</span><span style="color: #0000ff;">1</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
          <span style="color: #808080; font-style: italic;">//Skip the counter if it indicates the overall CPU usage,</span>
          <span style="color: #808080; font-style: italic;">//we only want the per-core values.</span>
          <span style="color: #000000; font-weight: bold;">if</span> InstanceId <span style="color: #000066;">=</span> <span style="color: #ff0000;">'_Total'</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000066;">continue</span><span style="color: #000066;">;</span>
&nbsp;
          <span style="color: #808080; font-style: italic;">//Add the counter to the query</span>
          status <span style="color: #000066;">:</span><span style="color: #000066;">=</span> PdhAddCounter<span style="color: #000066;">&#40;</span>Query<span style="color: #000066;">,</span> <span style="color: #000066; font-weight: bold;">PWideChar</span><span style="color: #000066;">&#40;</span>CounterPath<span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">,</span> h<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
          <span style="color: #000000; font-weight: bold;">if</span> status <span style="color: #000066;">=</span> ERROR_SUCCESS <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">begin</span>
&nbsp;
            <span style="color: #808080; font-style: italic;">//Expand the internal counter array if necessary</span>
            <span style="color: #000000; font-weight: bold;">if</span> cnt &gt; <span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">&#41;</span><span style="color: #000066;">-</span><span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">then</span>
              <span style="color: #000066;">SetLength</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">,</span> <span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">&#41;</span><span style="color: #000066;">+</span><span style="color: #0000ff;">16</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
            <span style="color: #808080; font-style: italic;">//Save the counter data to the array</span>
            <span style="color: #000000; font-weight: bold;">with</span> Counters<span style="color: #000066;">&#91;</span>cnt<span style="color: #000066;">&#93;</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
              Path <span style="color: #000066;">:</span><span style="color: #000066;">=</span> CounterPath<span style="color: #000066;">;</span>
              Handle <span style="color: #000066;">:</span><span style="color: #000066;">=</span> h<span style="color: #000066;">;</span>
&nbsp;
              <span style="color: #808080; font-style: italic;">//Create a label for this core/CPU</span>
              mLabel <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TLabel<span style="color: #000066;">.</span><span style="color: #006600;">Create</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">Self</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
              mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Parent</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">Self</span><span style="color: #000066;">;</span>
              mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Caption</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">'Core '</span><span style="color: #000066;">+</span>InstanceId<span style="color: #000066;">;</span>
              mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Top</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">&#40;</span>mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Height</span> <span style="color: #000066;">+</span> <span style="color: #0000ff;">8</span><span style="color: #000066;">&#41;</span> <span style="color: #000066;">*</span> cnt <span style="color: #000066;">+</span> <span style="color: #0000ff;">10</span><span style="color: #000066;">;</span>
              mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Left</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">10</span><span style="color: #000066;">;</span>
              mLabel<span style="color: #000066;">.</span><span style="color: #006600;">AutoSize</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">false</span><span style="color: #000066;">;</span>
              mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Width</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">80</span><span style="color: #000066;">;</span>
&nbsp;
              <span style="color: #808080; font-style: italic;">//Create a &quot;progress bar&quot; to show the core/CPU usage</span>
              mGauge <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TGauge<span style="color: #000066;">.</span><span style="color: #006600;">Create</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">Self</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
              mGauge<span style="color: #000066;">.</span><span style="color: #006600;">Parent</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">Self</span><span style="color: #000066;">;</span>
              mGauge<span style="color: #000066;">.</span><span style="color: #006600;">Top</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Top</span><span style="color: #000066;">;</span>
              mGauge<span style="color: #000066;">.</span><span style="color: #006600;">Left</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Width</span> <span style="color: #000066;">+</span> <span style="color: #0000ff;">20</span><span style="color: #000066;">;</span>
              mGauge<span style="color: #000066;">.</span><span style="color: #006600;">Height</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Height</span><span style="color: #000066;">+</span><span style="color: #0000ff;">2</span><span style="color: #000066;">;</span>
              mGauge<span style="color: #000066;">.</span><span style="color: #006600;">Width</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">Self</span><span style="color: #000066;">.</span><span style="color: #006600;">ClientWidth</span> <span style="color: #000066;">-</span> mGauge<span style="color: #000066;">.</span><span style="color: #006600;">Left</span> <span style="color: #000066;">-</span> <span style="color: #0000ff;">10</span><span style="color: #000066;">;</span>
              mGauge<span style="color: #000066;">.</span><span style="color: #006600;">ForeColor</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #9ac;">$0031D329</span><span style="color: #000066;">;</span>
              mGauge<span style="color: #000066;">.</span><span style="color: #006600;">Anchors</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">&#91;</span>akRight<span style="color: #000066;">,</span> akTop<span style="color: #000066;">&#93;</span><span style="color: #000066;">;</span>
&nbsp;
            <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
            <span style="color: #000066;">inc</span><span style="color: #000066;">&#40;</span>cnt<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
          <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
        <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span><span style="color: #808080; font-style: italic;">//while</span>
&nbsp;
        <span style="color: #808080; font-style: italic;">//Truncate the array to the actual number of discovered cores  </span>
        <span style="color: #000066;">SetLength</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">,</span> cnt<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;">//Collect the first data sample</span>
        PdhCollectQueryData<span style="color: #000066;">&#40;</span>Query<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
      <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">//Did we get any valid counters?</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">&#41;</span> <span style="color: #000066;">=</span> <span style="color: #0000ff;">0</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">begin</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">//Nope. Show an unhelpful error message...</span>
    MessageBox<span style="color: #000066;">&#40;</span>Handle<span style="color: #000066;">,</span> <span style="color: #ff0000;">'Initialization was unsuccessful. The application will now exit.'</span><span style="color: #000066;">,</span>
      <span style="color: #ff0000;">'Error'</span><span style="color: #000066;">,</span> MB_OK <span style="color: #000000; font-weight: bold;">or</span> MB_ICONEXCLAMATION<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">//...and quit.</span>
    Application<span style="color: #000066;">.</span><span style="color: #006600;">Terminate</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">end</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #808080; font-style: italic;">//Everything went well.</span>
    <span style="color: #808080; font-style: italic;">//Resize the form to make sure all progress bars are visible.</span>
    <span style="color: #000000; font-weight: bold;">Self</span><span style="color: #000066;">.</span><span style="color: #006600;">ClientHeight</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span>
      Counters<span style="color: #000066;">&#91;</span><span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">&#41;</span><span style="color: #000066;">-</span><span style="color: #0000ff;">1</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #006600;">mLabel</span><span style="color: #000066;">.</span><span style="color: #006600;">Top</span> <span style="color: #000066;">+</span>
      Counters<span style="color: #000066;">&#91;</span><span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">&#41;</span><span style="color: #000066;">-</span><span style="color: #0000ff;">1</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #006600;">mLabel</span><span style="color: #000066;">.</span><span style="color: #006600;">Height</span> <span style="color: #000066;">+</span>
      Counters<span style="color: #000066;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #006600;">mLabel</span><span style="color: #000066;">.</span><span style="color: #006600;">Top</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> TForm1<span style="color: #000066;">.</span><span style="color: #006600;">Timer1Timer</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
 i<span style="color: #000066;">:</span><span style="color: #000066; font-weight: bold;">integer</span><span style="color: #000066;">;</span>
 counterType<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">PDword</span><span style="color: #000066;">;</span>
 pValue<span style="color: #000066;">:</span>_PDH_FMT_COUNTERVALUE<span style="color: #000066;">;</span>
 status <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">if</span> Query <span style="color: #000066;">=</span> <span style="color: #0000ff;">0</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000066;">exit</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">//Collect a data sample.</span>
  PdhCollectQueryData<span style="color: #000066;">&#40;</span>Query<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">//Iterate over all counters and update progress bars.</span>
  <span style="color: #000000; font-weight: bold;">for</span> i <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">0</span> <span style="color: #000000; font-weight: bold;">to</span> <span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">&#41;</span> <span style="color: #000066;">-</span> <span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
    counterType <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">//Get the current core/CPU usage</span>
    status <span style="color: #000066;">:</span><span style="color: #000066;">=</span> PdhGetFormattedCounterValue<span style="color: #000066;">&#40;</span>
      Counters<span style="color: #000066;">&#91;</span>i<span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #006600;">Handle</span><span style="color: #000066;">,</span> <span style="color: #808080; font-style: italic;">//Counter handle as returned by PdhAddCounter.</span>
      PDH_FMT_DOUBLE<span style="color: #000066;">,</span>     <span style="color: #808080; font-style: italic;">//Get the counter value as a double-precision float.</span>
      CounterType<span style="color: #000066;">,</span>        <span style="color: #808080; font-style: italic;">//Counter type; unused.</span>
      pValue<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>            <span style="color: #808080; font-style: italic;">//Output buffer for the counter value.</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">//Update the progress bar.</span>
    <span style="color: #000000; font-weight: bold;">if</span> status <span style="color: #000066;">=</span> ERROR_SUCCESS <span style="color: #000000; font-weight: bold;">then</span>
      Counters<span style="color: #000066;">&#91;</span>i<span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #006600;">mGauge</span><span style="color: #000066;">.</span><span style="color: #006600;">Progress</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">Round</span><span style="color: #000066;">&#40;</span>pValue<span style="color: #000066;">.</span><span style="color: #006600;">doubleValue</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> TForm1<span style="color: #000066;">.</span><span style="color: #006600;">FormDestroy</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
 <span style="color: #808080; font-style: italic;">//Close the query when quitting.</span>
 <span style="color: #000000; font-weight: bold;">if</span> Query &lt;&gt; <span style="color: #0000ff;">0</span> <span style="color: #000000; font-weight: bold;">then</span> PdhCloseQuery<span style="color: #000066;">&#40;</span>Query<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">.</span></pre></div></div>

<h3>Download</h3>
<ul>
<li><strong><a href="http://w-shadow.com/files/CoreUsage.rar">Example source code</a></strong> (5 KB)<br />
This is a Delphi 2009 project. To compile it, you will also need to install the <a href="http://jedi-apilib.sourceforge.net/">Jedi API library</a> that contains PDH API headers for Delphi.</li>
<li><strong><a href="http://w-shadow.com/files/CpuCoreUsage.exe">Compiled example application</a></strong> (570 KB)</li>
</ul>
<p><em>P.S. </em><br />
Rumor has it that you may need administrative rights to use the performance counter API.</p>
<hr/>Copyright &copy; 2009 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/04/17/per-core-cpu-usage/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Text Classification With PHP</title>
		<link>http://w-shadow.com/blog/2009/03/07/text-classification-with-php/</link>
		<comments>http://w-shadow.com/blog/2009/03/07/text-classification-with-php/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 17:21:56 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[machine learning]]></category>
		<category><![CDATA[naive bayes]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[php classes]]></category>
		<category><![CDATA[spam filters]]></category>
		<category><![CDATA[text categorization]]></category>
		<category><![CDATA[text classifiers]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=971</guid>
		<description><![CDATA[Text classification is probably the most popular real-world application of machine learning and other AI techniques. This is because the adaptive spam filters that guard our inboxes, comment forms and guestbooks are basically specialized text classifiers that only deal with two categories &#8211; &#8220;spam&#8221; and &#8220;not spam&#8221;. Text categorization can also be used to detect [...]]]></description>
			<content:encoded><![CDATA[<p>Text classification is probably the most popular real-world application of machine learning and other AI techniques. This is because the adaptive spam filters that guard our inboxes, comment forms and guestbooks are basically specialized text classifiers that only deal with two categories &#8211; &#8220;spam&#8221; and &#8220;not spam&#8221;. Text categorization can also be used to detect the language of a document, automatically suggest categories or tags for textual content, and more.</p>
<p>As with most AI algorithms, there are relatively few PHP classes/libraries available that deal with automated text classification. In this post I&#8217;ll review the classifier scripts I managed to find.</p>
<p><em>Note : All of these scripts use some form of the <a href="http://en.wikipedia.org/wiki/Naive_Bayes_classifier">naive Bayes classifier</a>. This algorithm is easy to implement and usually yields pretty good results, but it&#8217;s worth knowing that <a href="http://en.wikipedia.org/wiki/Document_classification#Techniques">other techniques</a> exist.</em></p>
<h3><a href="http://xhtml.net/php/PHPNaiveBayesianFilter">PHP Naive Bayesian Filter</a></h3>
<p>This is a simple text classifier backed by a MySQL database. You can train it to recognize any number of categories, and it will also allow you to &#8220;untrain&#8221; the classifier if you mistakenly assign the wrong category to a document. The downside is that most of the documentation is in French, but that shouldn&#8217;t be a huge problem &#8211; the code itself is easy enough to understand and commented in English. See also : <a href="http://www.hokstad.com/archives/2005/03/php_naive_bayes.html">an English translation of the project&#8217;s page</a>.</p>
<h3><a href="http://nasauber.de/opensource/b8/index.php.en">b8</a></h3>
<p>b8 is an actively developed spam filter implemented in PHP. This is a good choice if you need a document classifier specifically for the purpose of catching forum/comment spammers. However, with a bit of modification you could probably coerce it to do other kinds of classification.</p>
<p>The filter can be trained/untrained and supports several database backends &#8211; BerkleyDB (very fast), MySQL (ubiquitous, but slower when used this way) and SQLite (a file-based database). The whole thing has a fairly professional overall look and good documentation.</p>
<h3><a href="http://www.phpclasses.org/browse/package/5072.html">PHP Text Classifier</a></h3>
<p>I felt I had to include this class for completeness, but I personally wouldn&#8217;t use it for anything but the simplest projects. The good news is that this classifier supports an arbitrary number of categories and has a very simple implementation (the GPL headers probably take up more space than the code itself). The bad news is that there&#8217;s almost no documentation, the source comments are in whatever language they speak in Indonesia, and storing word frequency data as a serialized object isn&#8217;t very scalable.</p>
<h3>Roll Your Own</h3>
<p>If the above scripts don&#8217;t suit your needs you can always write your own. For example, the Wikipedia pages on <a href="http://en.wikipedia.org/wiki/Bayesian_spam_filtering">Bayesian spam filtering</a> and <a href="http://en.wikipedia.org/wiki/Naive_Bayes_classifier">naive Bayes classifiers</a> have a good (if a somewhat math-heavy) overview a simple classification algorithm and a list of useful resources and tutorials. Good luck <img src='http://w-shadow.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<hr/>Copyright &copy; 2009 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/03/07/text-classification-with-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Top 4 Free Embedded Databases</title>
		<link>http://w-shadow.com/blog/2009/02/25/top-4-free-embedded-databases/</link>
		<comments>http://w-shadow.com/blog/2009/02/25/top-4-free-embedded-databases/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 22:26:03 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[embedded database]]></category>
		<category><![CDATA[freeware]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=937</guid>
		<description><![CDATA[I need an embedded database for my next project. During the last few days I&#8217;ve done a lot of virtual leg-work researching and comparing the various alternatives, trawling through documentation and forums. The results are below. Hopefully, if you&#8217;re ever in the same situation, this list will make your life a bit easier.
Of course, the [...]]]></description>
			<content:encoded><![CDATA[<p>I need an embedded database for my next project. During the last few days I&#8217;ve done a lot of virtual leg-work researching and comparing the various alternatives, trawling through documentation and forums. The results are below. Hopefully, if you&#8217;re ever in the same situation, this list will make your life a bit easier.</p>
<p>Of course, the list is far from comprehensive &#8211; it wasn&#8217;t really my goal to include every embedded database in existance, but rather to find those that fit the needs of the project. The focus was on speed, support for multi-threading and connectivity (what programming language interfaces are available for the DB). I also left out databases that are tied to a single language or framework (Java/.NET) &#8211; sorry about that, I know there are <a href="http://www.h2database.com/html/main.html">some</a> <a href="http://hsqldb.org/">good</a> <a href="http://www.db4o.com/">ones</a>.</p>
<p>Without further ado, here are my top choices (in minimalistic list format).</p>
<h3>#1 <a href="http://www.sqlite.org/">SQLite</a></h3>
<p><a href="http://www.sqlite.org/"><img src="http://w-shadow.com/wp-content/uploads/2009/02/sqlite.png" alt="SQLite" title="SQLite" width="327" height="97" class="alignnone size-full wp-image-945" /></a><br />
<strong>Connectivity</strong> : <a href="http://www.sqlite.org/cvstrac/wiki?p=SqliteWrappers">Any programming language (almost)</a><br />
<strong>Platforms</strong> : Linux, Mac OS X, OS/2, Windows (Win32 and WinCE) and embedded devices<br />
<strong>Footprint</strong> : 300 Kb (or 180 Kb with optional features ommitted)<br />
<strong>Model</strong>	  : Relational (SQL92 with <a href="http://www.sqlite.org/omitted.html">some exceptions</a>)<br />
<strong>License</strong>  : Public domain</p>
<blockquote><p>SQLite is a software library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine. SQLite is the most widely deployed SQL database engine in the world. The source code for SQLite is in the public domain. Includes both a native C library and a simple command line client for its database.</p></blockquote>
<p><strong>Highlights : </strong></p>
<li>+ If you start looking into embedded databases, you won&#8217;t be able to make a step without tripping over some SQLite evangelist. This database engine is definitely one of the most popular, so there&#8217;s a lot of tutorials for nearly any language available, plus a huge community of users to help you out.</li>
<li>+ It&#8217;s fast, robust and &#8220;just works&#8221;. Hey, even Firefox uses it.</li>
<li>- Referential integrity (i.e. foreign keys) isn&#8217;t enforced. However, you can work around this by using triggers.</li>
<li>- No ALTER TABLE command and no stored procedures.</li>
<li>- Limited support for concurrent access/multi-threading.</li>
<li>Column datatypes aren&#8217;t enforced &#8211; you can store any data of any length in any column. Whether this is a flaw or a benefit really depends on what you want to do with it.</li>
</ul>
<h3>#2 <a href="http://www.firebirdsql.org/">Firebird SQL</a></h3>
<p><a href="http://www.firebirdsql.org/"><img src="http://w-shadow.com/wp-content/uploads/2009/02/ds-firebird-logo-90.png" alt="Firebird SQL" title="Firebird SQL" width="90" height="90" class="alignnone size-full wp-image-944" /></a><br />
<strong>Connectivity</strong> : <a href="http://www.firebirdfaq.org/cat9/">.NET, C/C++, Delphi, Java, PHP, Perl, Python, VB, COBOL, etc</a> (<a href="http://www.firebirdnews.org/docs/fb2min.html">see also</a>)<br />
<strong>Platforms</strong> : Windows (Win 98 and up), Linux (<a href="http://www.firebirdfaq.org/Firebird-Embedded-Linux-HOWTO.html">tricky</a>)<br />
<strong>Footprint</strong> : 4-5 MB<br />
<strong>Model</strong> : Relational (SQL92 and most of SQL99)<br />
<strong>License</strong> : Open source (LGPL)</p>
<blockquote><p>Firebird is a relational database offering many ANSI SQL standard features. (&#8230;) Firebird offers excellent concurrency, high performance, and powerful language support for stored procedures and triggers. It has been used in production systems, under a variety of names, since 1981.</p></blockquote>
<p><strong>Highlights : </strong></p>
<ul>
<li>+ Referential integrity is supported, which is nice when compared to SQLite.</li>
<li>+ Concurrency support is also decent.</li>
<li>+ Supports triggers <em>and</em> stored procedures.</li>
<li>- A notably confusing and disjointed website. I had to dig around for a while to find out what I needed to know. Some sections also present outdated information.</li>
<li>- No built-in full text search.</li>
<li>- If you casually browse around Friebird&#8217;s site you may get the impression that the embedded version only works with .NET (they even have an entire sub-website dedicated to the .NET version). However, you can actually use it with many other languages by downloading the embedded version and using the standard Firebird APIs.</li>
</ul>
<h3>#3 <a href="http://www.scimore.com/products/embedded.aspx">ScimoreDB</a></h3>
<p><a href="http://www.scimore.com/products/embedded.aspx"><img src="http://w-shadow.com/wp-content/uploads/2009/02/scimore-db.jpg" alt="Scimore DB" title="Scimore DB" width="491" height="100" class="alignnone size-full wp-image-943" /></a><br />
<strong>Connectivity</strong> : C++, .NET, Delphi (discontinued?)<br />
<strong>Platforms</strong> : Windows (XP,  Vista, Windows Server 2000 &#8211; Windows Server 2008)<br />
<strong>Footprint</strong> : &lt; 4 MB<br />
<strong>Model</strong> : Relational<br />
<strong>License</strong> : Free for commercial and non-commercial use</p>
<p>(There is no quote here because almost everything on the website reads like a shallow advertisement. Nevertheless, the <a href="http://www.scimore.com/products/key-Features.aspx">feature list</a> looked attractive enough.)</p>
<p><strong>Highlights :</strong> </p>
<li>+ ScimoreDB can be used both as an in-process and out-of-process engine, which results in very good concurrency support (at some speed penalty).</li>
<li>+ Table level and row level locking is supported. </li>
<li>+ Foreign keys Referential integrity works.</li>
<li>- C++ interface is a bit awkward and the Delphi components are apparently in limbo.</li>
<h3>#4 <a href="http://www.oracle.com/technology/products/berkeley-db/db/index.html">Oracle Berkley DB</a></h3>
<p><a href="http://www.oracle.com/technology/products/berkeley-db/db/index.html"><img src="http://w-shadow.com/wp-content/uploads/2009/02/berkeley-db-logo.gif" alt="Berkley DB" title="Berkley DB" width="125" height="61" class="alignnone size-full wp-image-942" /></a><br />
<strong>Connectivity</strong> : C, C++, Java, Tcl<br />
<strong>Platforms</strong> : *nix, Windows, Windows CE, VxWorks, S60, BREW<br />
<strong>Footpring</strong> : 400 Kb (minimum)<br />
<strong>Model</strong> : Key-value<br />
<strong>License</strong> : Open source (<a href="http://www.oracle.com/technology/software/products/berkeley-db/htdocs/licensing.html">dual-licensed</a>) </p>
<blockquote><p>Berkeley DB delivers the same robust data storage features as traditional, relational database systems, such as ACID transactions and recovery; locking, multiple processes and multi-threading for high concurrency; hot and cold backup; and single-master replication for high availability applications. Berkeley DB can manage databases in memory, on disk or both.</p></blockquote>
<p><strong>Highlights : </strong></p>
<li>This is the only item on the list that doesn&#8217;t use some form of SQL. Instead, Berkley DB stores key-value pairs. There is no query language.</li>
<li>+ Thanks to the simple architecture and long history of development, Berkley DB has extremely good scalability and performance.</li>
<li>- The key-data database structure may not be suitable for your projects.</li>
<li>- Dual licensing means it&#8217;s only free if your application is also distributed as open source. If you want to use this embedded database engine in a closed-source, commercial application, you will need to pay licensing fees.</li>
<hr/>Copyright &copy; 2009 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/02/25/top-4-free-embedded-databases/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Make Your Plugin Faster With Conditional Tags</title>
		<link>http://w-shadow.com/blog/2009/02/22/make-your-plugin-faster-with-conditional-tags/</link>
		<comments>http://w-shadow.com/blog/2009/02/22/make-your-plugin-faster-with-conditional-tags/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 22:09:17 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[website speed]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress plugins]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=920</guid>
		<description><![CDATA[One of the reasons why WordPress can be slow is that it loads all active plugins on each and every page, even if some of those plugins aren&#8217;t actually used on that page. For example, an active anti-spam plugin will still be loaded even if the current page doesn&#8217;t contain a comment form (e.g. category [...]]]></description>
			<content:encoded><![CDATA[<p>One of the reasons why WordPress can be slow is that it loads <strong>all</strong> active plugins on each and every page, even if some of those plugins aren&#8217;t actually used on that page. For example, an active anti-spam plugin will still be loaded even if the current page doesn&#8217;t contain a comment form (e.g. category pages and date archives). There&#8217;s not a lot we can do about that as users except complaining incessantly. However, if you&#8217;re a plugin author, there are a few tricks that you can and should use to <strong>make your plugin load only when required</strong>.</p>
<h3>Divide And Conquer</h3>
<p>The basic idea is to split the plugin into several .php files and load only the necessary components on each particular page. The main plugin file should contain only the code that decides which other files to load (e.g. by using <a href="http://codex.wordpress.org/Conditional_Tags">conditional tags</a>). For example, if your plugin only needs to run in the Dashboard, you could place all the important code in &#8220;admin.php&#8221; and put this in the main file :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">/*
...the plugin header...
*/</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Are we running in the Dashboard?</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> is_admin<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//Load the actual plugin</span>
    <span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'admin.php'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>This way all the complex functionality &#8211; the &#8220;meat&#8221; of your plugin &#8211; won&#8217;t be needlessly loaded when someone visits the blog&#8217;s homepage or browses the archives, and the site will be a little bit faster as a result. </p>
<h3>The Tricky Part</h3>
<p>The above example works fine if you use the <code>is_admin()</code> function, but it won&#8217;t work as expected with other conditional tags like <code>is_single</code> and <code>is_category</code> &#8211; they will always return <code>false</code>. This is because WordPress loads plugins very early, before it has parsed the current URL and figured out what it points to.</p>
<p>To get around this you can hook your loader script to the <a href="http://codex.wordpress.org/Plugin_API/Action_Reference#Advanced_Actions">&#8220;wp&#8221;</a> action. This action executes right after the query has been parsed and posts have been loaded, so the conditional tags will return correct values by then.</p>
<p>The new script might look like this :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Are we in the Dashboard?</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> is_admin<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//Yep. Load the backend.</span>
    <span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'admin.php'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//Nope. Set a hook to execute when other conditional tags are available.</span>
    add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'wp'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'load_test_plugin'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> load_test_plugin<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//You can use most conditional tags here.</span>
    <span style="color: #666666; font-style: italic;">//For example, load the plugin only when viewing a single page or post : </span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> is_singular<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">//Load the actual plugin</span>
        <span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'core.php'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>And presto, optimization! <img src='http://w-shadow.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Caveats</h3>
<ul>
<li>You can&#8217;t use the above method if your plugin needs to interact with one of the actions/filters that run before the <code>wp</code> action.</li>
<li>Be aware of variable scope. When you include a file inside a function (like the hook above), any variables defined in the file will only be accessible from within that function. If you need a variable to be global, declare it explicitly with the &#8220;global&#8221; keyword.</li>
<li>Another thing to keep in mind is that in this scenario the <code>__FILE__</code> constant won&#8217;t always point to the main plugin file.</li>
<li>It can be very hard to restructure an existing plugin to use the architecture suggested above, especially if it is very complex and needs to interact with many different hooks and filters.</li>
</ul>
<p>Now I wish more of my 32 active plugins were optimized like this <img src='http://w-shadow.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  As far as I know, <a href="http://planetozh.com/blog/my-projects/wordpress-admin-menu-drop-down-css/">Ozh&#8217;s dropdown menu</a> is the only one of them that uses this structure.</p>
<hr/>Copyright &copy; 2009 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/02/22/make-your-plugin-faster-with-conditional-tags/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
