May 212015
 

One of the benefits of an object oriented programming language is that functionality can be built into the object hierarchy in layers, deferring some details to a descendant while providing common functionality in a base class and avoiding repetition. However, when a group of classes all need to implement nearly the same method but with minor, class specific differences (more than just a constant), a curious anti-pattern tends to arise. In this situation, the base class implementation contains different behaviors based on the type identification of the true object even though we desire to push those implementations to the descendants.

In the Star Wars Combine’s (SWC) codebase there are several examples of this, but today we’ll use one from the actions system to illustrate the point. In this game, there are many different forms of travel, each of which works mostly the same way. Each works in steps, where the system establishes a deadline for the next travel update and then changes an entity’s position after it expires. There are also common behaviors that need to be included, such as awarding experience points and sending events when travel expires.

The core functionality is captured in the abstract class StepTravelAction, which defines several key methods:

abstract class StepTravelAction extends BaseAction {

	public function setup(Entity $leader, $x, $y) {
		// ...
	}

	public function timerInterrupt(TimerInterrupt $payload) {
		// ...
	}

	public function abort() {
		// ...
	}

	public function finishTravelling($reason = null) {
		$leader = $this->leader;
		$travelType = $this->getTravelType();
		$party = $this->getParty();

		XPUtil::giveTravelXP($this->leader, $party, $this->XP, 'Finished ' . $this->getEventText());
		RewardUtil::testUniqueRewards($this->leader, enumRewardType::GROUND_TRAVEL);

		foreach ($this->getParty() as $member) {
			$member->travelID = null;
		}
		EntityLocationUtil::saveEntityLocation($leader);

		$this->delete();

		if ($reason == null) {
			$reason = TravelEndInterrupt::FINISH_NORMAL;
		}
		
		InterruptUtil::fire($leader, new TravelEndInterrupt($leader, $travelType, $reason));
	}

	abstract public function setupTravel();
	abstract public function applyStep(Entity $leader, Point $next);
	abstract public function getTravelType();
	// ...

}

Although the function bodies for some functions have been removed in the interest of space, we can see the core functionality, like aborting or finishing travel, is handled here in the base class. The concrete, travel type-specific details of things, like updating the entity’s position, are farmed out to the derived classes.

However, at some point, it was decided that ground travel was awarding too much experience and could be abused by players (mostly to power level NPCs who can be set to patrol a location indefinitely, which takes months otherwise). Experience is awarded inside finishTravelling() as we can see, which is “common” to all of the travel action classes. At this point, there are several options for modifying the implementation, and the “simplest” in a language with dynamic type identification produces a design antipattern.

To reduce the XP awarded in ground travel only, an earlier programmer elected to add three lines to StepTravelAction::finishTravelling(), quickly resolving the issue:

	public function finishTravelling($reason = null) {
		// ...

		if ($this instanceof GroundTravelAction) {
			$this->XP = ceil($this->XP / 5);
		}

		// ...
	}

This ignores the benefits of object inheritance, produces less elegant code, and reduces the sustainability of the code in the future. Behavior specific to GroundTravelAction is now no longer contained within GroundTravelAction itself, so if we wanted to further modify the XP for this case, a lot of code walking would be needed to figure out where to do it. If multiple such exceptions are added, you might as well not have support for polymorphism at all and do everything in a single struct that stores type IDs and uses switch statements, taking us back to the early 80s. Exceptions like this were added to several other methods (abort(), etc.) for the same change as well.

The correct approach here is to refactor this method into three different components:

  1. a concrete version of finishTravelling that follows the original implementation
  2. a virtual method implemented in StepTravelAction that simply forwards to the concrete implementation
  3. a virtual method in the descending class that layers additional functionality (such as changing the XP to be awarded) and then calls the concrete version from its parent

We need all three components because the default implementation is correct in most cases, so it should be available as the default behavior, but when we want to modify it we still need to have the original version available to avoid copying and pasting it into the derived class. I think it might be even worse if someone were to simply use a virtual method and copy it entirely into the derived class in order to add three lines.

For completeness, a preferable implementation would look like this and preserve the same behavior for all other derived classes:

abstract class StepTravelAction extends BaseAction {

	protected function _finishTravelling($reason = null) {
		$leader = $this->leader;
		$travelType = $this->getTravelType();
		$party = $this->getParty();

		XPUtil::giveTravelXP($this->leader, $party, $this->XP, 'Finished ' . $this->getEventText());
		RewardUtil::testUniqueRewards($this->leader, enumRewardType::GROUND_TRAVEL);

		foreach ($this->getParty() as $member) {
			$member->travelID = null;
		}
		EntityLocationUtil::saveEntityLocation($leader);

		$this->delete();

		if ($reason == null) {
			$reason = TravelEndInterrupt::FINISH_NORMAL;
		}
		
		InterruptUtil::fire($leader, new TravelEndInterrupt($leader, $travelType, $reason));
	}

	public function finishTravelling($reason = null) {
		$this->_finishTravelling($reason);
	}

}

class GroundTravelAction extends StepTravelAction {

	public function finishTravelling($reason = null) {
		$this->XP = ceil($this->XP / 5);
		$this->_finishTravelling($reason);
	}

}

The reason I want to highlight this is that the problem arose despite the developer having a familiarity with inheritance and deferring implementation details to derived classes where meaningful. There are abstract methods here and they are used to plug into common functionality implemented within StepTravelAction, but while targeting a change in behavior it is easy to lose sight of the overall design and simply insert a change where the implementation is visible. This kind of polymorphism antipattern is one of the most common implementation issues in SWC, likely due to the availability of the instanceof operator in PHP. In C++ it is a lot harder to do this (although RTTI does exist, I never use it), and people are often forced to learn the correct approach as a result.

Apr 072013
 

While doing some updates to the blog, such as adding author information and other useful information to hopefully help with legitimatizing things, I spent about two hours trying to figure out why a shortcode in the theme that I use (Suffusion) would not parse arguments. The tag suffusion-the-author would display author name, but if I added an argument to make it display the description or a link instead of just the name, it would always fail and revert to the author name only. Some quick googling told me that this didn’t seem to be a problem anyone else had, and after four major versions for the theme, I’m pretty sure someone would’ve noticed if a basic feature were entirely nonfunctional. After lots of debugging, I discovered that the problem was happening in WordPress’s code, inside the definition of shortcode_parse_atts(), which parses the attributes matched in the shortcode into an array for use inside the callback. For me, instead, it killed all of the tag arguments and returned an empty string. In the end I found that the issue was a regular expression that appears to be designed to replace certain types of unicode spaces with normal spaces to simplify the argument parsing regular expression that comes after

$text = preg_replace("/[\x{00a0}\x{200b}]+/u", " ", $text);

On my system, this would simply set $text to an empty string, every time. Initially, I wanted to just comment it out, because I’m not expecting to see any of these characters inside tags, but that bothered me, because this has been a part of the WordPress code for a very long time, and nobody else appears to have problems with it. Finally, I concluded that this must mean that unicode support was not enabled, so I began searching through yum. Bad news, mbstring and pcre were all already installed, and php -i told me that php was built with multibyte string support enabled, as well as pcre regex support. I tested my pcre libraries and they claimed to support unicode as well.

In the end, I solved the problem by updating php and pcre to the latest version, which was an update from php-5.3.13 to php-5.3.24 in my case, and pcre was updated from 7.x to 8.21. It appears that there was some kind of incompatibility between php 5.3 and the 7.x branch of pcre (if you build php 5.3 from source, it will target pcre 8.x), which prevented me from using unicode despite support for it being present everywhere. So, if you have trouble getting your php installation to handle unicode inside regular expressions, and you’re running on Amazon Web Services, make sure you update to the latest versions of php and pcre, as there appear to be some issues with older packages.

May 102012
 

A few weeks ago, the online gaming community that I belong to (The Legion) deployed a new website to integrate information about the professional e-sports teams with the existing community, forum-based website. As a part of that, we wanted to include the ability to embed and view streams on the home page, with additional information about stream status. Luckily, twitch.tv includes a very powerful and flexible REST API for determining if a stream is online, with output formats in XML, JSON, or JSONP. After the preliminary support for twitch.tv was added, which covered most of the community, we wanted to add the ability to embed streams from another popular streaming website, own3d.tv, as there are a few popular players on the team who use it instead.

Unfortunately, own3d.tv’s API is significantly lacking in features. While twitch.tv returns extensive metadata about the channel, including game played, stream title, streamer name (popular channels can have multiple people stream to them at different times), viewers, preview image URLs, and other interesting information, the entire own3d.tv response consists of stream status (live/not), viewer count, and time spent streaming. To make matters worse, the own3d.tv API is undocumented and appears to have a single endpoint that returns data only in XML format: http://api.own3d.tv/liveCheck.php?live_id=(integer id here). The twitch.tv REST API allows a user to request information about any number of channels simultaneously, while the own3d API appears to only allow a single query per request.

Due to the way that cross-domain AJAX requests are handled (i.e. they aren’t), JSONP emerges as the most useful format for a REST API to be used in building a web application using javascript. I don’t know if this is the standard approach, but the easiest thing to do with twitch.tv appears to be to define a handler function, such as handleTwitchResponse and then insert a script tag into the HTML referencing the REST API endpoint as a source for script, with output set to JSONP and the appropriate handler supplied:

<script type="text/javascript" src="http://api.justin.tv/api/stream/list.json?channel=channel1,channel2,channel3&jsonp=handleTwitchResponse">

The resulting object supplied by twitch.tv’s servers will be wrapped in a function call to handleTwitchResponse, which immediately hooks it into your own local processing system. It would be great if own3d.tv supported the same approach (for flexibility), but it does not, so we are forced to create our own workaround.

To that end, I wrote a short php script that exposes an interface similar to the one used by twitch.tv, where a JSONP handler can be supplied, along with multiple stream IDs, and the results will be returned in an array:

/**
 * Script to forward requests to own3d.tv and return them in JSONP format for our
 * local stuff to handle.
 */

$ids = explode(',', $_GET['live_id']);
$outout = array();

foreach ($ids as $id) {
	$xml = file_get_contents('http://api.own3d.tv/liveCheck.php?live_id='.((int)$id));
	$sxml = new SimpleXMLElement($xml);
	$results = array('isLive' => (string)$sxml->liveEvent->isLive,
					'liveViewers' => (int)$sxml->liveEvent->liveViewers,
					'live_id' => (int)$id,
					'liveDuration' => (int) $sxml->liveEvent->liveDuration);
	$output[] = $results;
}

if (isset($_GET['jsonp']))
	echo $_GET['jsonp'].'('.json_encode($output).');';
else
	echo json_encode($output);

The script itself is pretty simple, as mostly it just glues together a few pieces and changes the format of the data. A comma-separated list of IDs is expected as a GET parameter, along with an optional JSONP callback, presenting a format almost identical to the twitch.tv interface. If no callback is supplied, standard JSON formatting is used instead. Using the ability to make HTTP requests via fopen() (which requires Allow fopen URL wrappers to be set to true in php.ini), it fetches information for each ID individually from own3d.tv, then parses the XML into a PHP array, and spits it out using the built-in JSON-encoding functions provided within PHP.

Note: This script does not translate the names used by own3d.tv to match those used by twitch.tv, but it does add the live_id to the response, in order to allow you to identify which stream a particular status object corresponds to when receiving multiple aggregated into a single response. I did this somewhat intentionally, because it is more useful as a drop in replacement for systems that wish to conserve the own3d.tv naming conventions. You can also readily rename the javascript object properties after all the data has been received by the client, before forwarding the object to a standard twitch.tv handler, which means that it’s also kind of a moot argument.

The script should be stored locally on your server. Then, it can be accessed with standard AJAX, or, for consistency, in a manner identical to how the twitch.tv script is referenced:

<script type="text/javascript" src="own3d_check.php?live_id=1234,1235,1236&jsonp=handleOwnedResponse"></script>

If you find yourself in a situation where you need to deal with own3d.tv streams and their API before it is improved, feel free to use the above script as a reference (or just borrow it I suppose?). Hopefully they will realize that twitch.tv is leagues ahead of them at the moment in this aspect of web streaming, and in order to stay competitive they need to address API needs of external websites.

Aug 022011
 

A few days ago, I had what I expect is a common problem: I needed to print off some PDFs, sign them, and then scan them back into PDF format to return. However, I didn’t have any software for scanning directly to PDF, and most solutions on the internet appear to be either sketchy or cost money. The scanner functionality that is provided with Windows for working with TWAIN devices can create TIFF format images of the scanner output, so all I really needed was a solution that would allow me to create a PDF and insert a TIFF image. Luckily, there is a PECL package for creating PDF files using a PHP script, so I wrote a small command line PHP script to take a series of TIFF images and create a PDF, with one image per page.

Setting up PHP’s PDFLib Front End

Because the front-end for PDFLib is (now) a PECL package, it is not bundled with PHP, so you must retrieve it using the PEAR tool. Unfortunately, the PHP frontend requires a separate installation of PDFLib, so I began by obtaining a copy of the free for non-commercial use of PDFLib-Lite. As a home user only interested in converting some things that I scanned to email to a friend, I believe that I qualify for non-commercial use. Because there is no RPM of PDFLib Lite for Amazon’s Basic Linux AMI, I had to build from source, which was routine except that the initial image does not include gcc for some reason, so I had to install it as well. For reference, or for those new to Linux:

# wget http://www.pdflib.com/binaries/PDFlib/705/PDFlib-Lite-7.0.5.tar.gz
# tar -zxvf PDFlib-Lite-7.0.5
# cd PDFlib-Lite-7.0.5
# ./configure
# make
# make install

Now that PDFlib-Lite is installed to /usr/local it is necessary to download and install the PECL extension to expose it to PHP. On an Amazon virtual server instance it is necessary to install the php-devel package as well as the php-pear package first with yum, in order to have the necessary source and headers to build extensions, along with the tools to access PEAR; others may need to install it as well, depending on their setup. After that, installing new PHP extensions via PEAR is easy:

# pear install pecl/pdflib

Finally, add the extension to your configuration file, /etc/php.ini. Some configurations recommend putting extensions in their own files, which I think is kind of silly, but I’ll play along, so an alternative is to create a file in /etc/php.d/ named pdf.ini with only one line:

extension=pdf.so

In the event that after installing pdflib your extension has a different name, PEAR will tell you what to use after it is done installing.

Using PHP to Create PDFs

With all the libraries installed, I just needed a simple script that would create a new PDF, load up some TIFF-format images, and then insert them as full pages. So, I wrote this small command line script that accepts a list of input files and produces a PDF using one image per page, with each image resized to occupy the entire 8.5″x11″ page. It can be run in Windows or Linux using the PHP CLI, given that the appropriate software is installed, because it should be invoked with the php -f pdf_convert.php [arguments ...] syntax from any prompt, rather than relying on a #!/bin/php at the top of the file.

<?php
/**
 * Convert a series of TIFF files given on the command line to pages in
 * a single PDF
 */

if ($argc < 3) {
	echo ('Convert a series of TIFF images as individual pages in a PDF');
	echo ("\n".'Usage: php -f pdf_convert.php <output name> <input 1> <input 2> ...');
	exit(0);
}

// Get file names from command line
$output_file = $argv[1];
$input_files = array();
for ($i = 2; $i < $argc; ++$i) {
	$input_files[] = $argv[$i];
}

// Initialize PDF File
$pdf = new PDFLib();
if ($pdf->begin_document('', '') == 0) {
	die('Error: '.PDF_get_errmsg($pdf));
}

// For each of the input images, load them, create an 8.5" x 11" page, place them as
// the full page, and then close the page
foreach ($input_files as $in_file) {
	echo ('Now processing '.$in_file.'...'."\n");
	$pdf->begin_page_ext(612, 792, '');
	$image = $pdf->load_image('auto', $in_file, '');
	$pdf->fit_image($image, 0, 0, 'boxsize {612 792} fitmethod meet');
	$pdf->close_image($image);
	$pdf->end_page_ext('');
}

$pdf->end_document('');

$raw_pdf = $pdf->get_buffer();

file_put_contents($output_file, $raw_pdf);

echo ('Done!'."\n");

?>

This doesn’t do much in the way of error checking or proper handling, because it didn’t seem necessary for something I’m only going to use once or twice and isn’t really a packaged product. Feel free to use this or modify it for whatever you like, under the terms of the GPL.