Proof facebook is bad for you
I’ve always known that Facebook is bad for you. Now I have proof, http://www.sciencedaily.com/releases/2011/05/110523091541.htm
;-P
I’ve always known that Facebook is bad for you. Now I have proof, http://www.sciencedaily.com/releases/2011/05/110523091541.htm
;-P
You can send SMS (TXT Messages) for free to most Phone carriers by sending an email to their Email to SMS gateway.
A list of carriers email to SMS gateways is here:
http://en.wikipedia.org/wiki/List_of_SMS_gateways
I wrote a class based on this a while ago but never got around to finishing it:
< ?php
/**
* Send SMS via Email to SMS gateways
*
* Please note that the list of carreirs is UTF-8 encoded. ie: Mexico != México
*
* @author gabe@fijiwebdesign.com
* @link http://www.fijiwebdesign.com/
*/
class email2sms {
/**
* A list of the major Phone carriers and their Email 2 SMS gateway syntax
* Compiled from: http://en.wikipedia.org/wiki/List_of_carriers_providing_SMS_transit
*/
protected static $carriers = array(
array("Airtel", "Andhra Pradesh, India", "#@airtelap.com"),
array("Airtel", "Karnataka, India", "#@airtelkkk.com"),
array("Alaska Communications Systems", "USA", "#@msg.acsalaska.net"),
array("Alltel Wireless Verizon Wireless", "USA", "#@text.wireless.alltel.com,#@mms.alltel.net"),
array("aql", "UK", "#@text.aql.com"),
array("AT&T Wireless", "USA", "#@txt.att.net,#@mms.att.net"),
array("AT&T", "USA", "#@mmode.com"),
array("AT&T Mobility", "USA", "#@mms.att.net,#@txt.att.net,#@cingularme.com"),
array("AT&T", "USA", "#@page.att.net"),
array("Bell", "Canada", "#@txt.bell.ca,#@txt.bellmobility.ca"),
array("Boost Mobile", "USA", "#@boostmobile.com"),
array("Bouygues Télécom (company)", "France", "#@mms.bouyguestelecom.fr"),
array("[[Loop_Mobile_India|Loop] (BPL Mobile)", "Mumbai, India", "#@bplmobile.com"),
array("Cellular One", "USA", "#@mobile.celloneusa.com"),
array("Cingular", "USA", "#@cingular.com"),
array("Centennial Wireless", "United States, Puerto Rico, U.S. Virgin Islands", "#@cwemail.com"),
array("Cincinnati Bell", "Cincinnati, Ohio, USA", "#@gocbw.com,#@mms.gocbw.com"),
array("Claro", "Brasil", "#@clarotorpedo.com.br"),
array("Claro", "Nicaragua", "#@ideasclaro-ca.com"),
array("Comcel", "Colombia", "#@comcel.com.co"),
array("Cricket", "", "#@mms.mycricket.com,#@sms.mycricket.com"),
array("CTI Móvil Claro", "Argentina", "#@sms.ctimovil.com.ar"),
array("Emtel", "Mauritius", "#@emtelworld.net"),
array("Fido", "Canada", "#@fido.ca"),
array("General Communications Inc.", "Alaska", "#@msg.gci.net"),
array("Globalstar satellite", "", "#@msg.globalstarusa.com"),
array("Helio", "", "#@myhelio.com"),
array("Iridium", "", "#@msg.iridium.com"),
array("i-wireless (Sprint PCS)", "", "#@iwirelesshometext.com"),
array("Mero Mobile", "Nepal", "#@sms.spicenepal.com"),
array("MetroPCS", "", "#@mymetropcs.com"),
array("Movicom", "", "#@movimensaje.com.ar"),
array("Mobitel", "Sri Lanka", "#@sms.mobitel.lk"),
array("Movistar", "Colombia", "#@movistar.com.co"),
array("MTN", "South Africa", "#@sms.co.za"),
array("MTS Mobility", "Canada", "#@text.mtsmobility.com"),
array("Nextel", "United States", "#@messaging.nextel.com"),
array("Nextel", "México", "#@msgnextel.com.mx"),
array("Nextel", "Argentina", "#@nextel.net.ar"),
array("Orange Polska", "Poland", "#@orange.pl"),
array("Personal", "Argentina", "#@alertas.personal.com.ar"),
array("Plus", "Poland", "#@text.plusgsm.pl"),
array("PC Telecom", "Canada", "#@mobiletxt.ca"),
array("Qwest Wireless", "USA", "#@qwestmp.com"),
array("Rogers Wireless", "Canada", "#@pcs.rogers.com"),
array("SaskTel", "Canada", "#@sms.sasktel.com"),
array("Setar", "Aruba", "#@mas.aw"),
array("Sprint (PCS)", "USA", "#@messaging.sprintpcs.com,#@pm.sprint.com"),
array("Sprint (Nextel)", "USA", "#@page.nextel.com,#@messaging.nextel.com"),
array("Suncom", "", "#@tms.suncom.com"),
array("Sunrise Communications", "Switzerland", "#@gsm.sunrise.ch"),
array("Syringa Wireless", "USA", "#@rinasms.com"),
array("T-Mobile", "USA", "#@tmomail.net"),
array("T-Mobile", "Austria", "#@sms.t-mobile.at"),
array("T-Mobile", "Croatia", "#@sms.t-mobile.hr"),
array("Telus Mobility", "Canada", "#@msg.telus.com"),
array("Tigo", "Colombia", "#@sms.tigo.com.co"),
array("Tracfone", "", "#@mmst5.tracfone.com,#@txt.att.net,#@tmomail.net,#@vtext.com,#@email.uscc.net,#@message.alltel.com"),
array("Unicel", "USA", "#@utext.com"),
array("US Cellular", "USA", "#@email.uscc.net,#@mms.uscc.net"),
array("Verizon", "USA", "#@vtext.com,#@vzwpix.com"),
array("Viaero", "USA", "#@viaerosms.com,#@mmsviaero.com"),
array("Vivo", "Brasil", "#@torpedoemail.com.br"),
array("Virgin Mobile", "Canada", "#@vmobile.ca"),
array("Virgin Mobile", "USA", "#@bills.com,#@vmobl.com,#@vmpix.com"),
array("Vodacom", "South Africa", "#@voda.co.za")
);
/**
* Send an SMS to a Phone Number
* @return Bool
* @param $msg String SMS/TXT message
* @param $to Int Receivers Phone number
* @param $from String From Email address or phone number
* @param $carrier String Carrier Name (index of self::$carriers)
*
* @todo at the moment we only send to the first listed email
* In the future it would be good to check the existence of mailbox at each domain
*
*
*/
public function send($msg, $to, $carrier, $from) {
$carriers = self::$carriers;
if (!isset($carriers[$carrier])) {
throw new Exception('The requested carrier was not found');
return false;
}
$addresses = explode(',', $carriers[$carrier][2]);
$address = str_replace('#', $to, $addresses[0]);
if (!mail($address, $msg, $msg, "from:$from\n")) {
throw new Exception('The Email could not be sent to SMS gateway');
return false;
}
return true;
}
/**
* Return a Carrier by phone number
* @return Array
* @param $name String
*/
public function getCarrierByNumber($number) {
// todo
// here we would query MTA at each domain for mailbox existence
}
/**
* Return a Carrier by name
* @return Array
* @param $name String
*/
public function getCarrierByName($name) {
return isset(self::$carriers[$name]) ? self::$carriers[$name] : null;
}
/**
* Retrieve a list of Carriers by region
* @return Array
* @param $region String[optional] Return only gateways in this region. eg: "USA" or "India"
*/
public function getCarriersByRegion($region = false) {
$carriers = self::$carriers;
if ($region) {
$_carriers = array();
$region = strtolower($region);
foreach($carriers as $carrier) {
if (in_array($region, explode(', ', strtolower($carrier[1])))) {
$_carriers[] = $carrier;
}
}
return $_carriers;
}
return $carriers;
}
/**
* Retrieve the regions in carrier list
* @return Array
*/
public function getRegions() {
$regions = array();
foreach(self::$carriers as $carrier) {
$regions[$carrier->region] = 1;
}
return array_keys($regions);
}
}
?>
Here is a PHP class that provides an interface for reading the PHP session data.
PHP alone only gives you access to the current users session. This class allows you to read all session files, and thus allow you to read session data across different users.
This may be useful if you want to copy, backups session data, or transfer to a different format/handler etc..
At the moment it only reads file based session handling, with PHP doing the serializing and handling (the default setting). It does not support other session handlers or serializers.
You can extend the base abstract class for different handlers and serializations.
/**
* Class for retrieving session data when save handler is files
*
* Features:
* Retrieving of all session data saved by PHP, not just the current user
* Encoding and decoding in PHP session format (not serialize|unserialize)
*
* @author gabe@fijiwebdesign.com
* @link http://www.fijiwebdesign.com/
*
*/
class FileSessionData extends AbstractSessionData
{
/**
* @var array Sesssion Files
*/
static $sess_files;
/**
* @var array Session Ids
*/
static $sess_ids;
/**
* Do not call constructor, use FileSessionData::singleton();
*/
protected function __construct()
{
// configs
$this->handler = ini_get('session.save_handler');
$this->save_path = ini_get('session.save_path');
// make sure session is using files
if ( $this->handler !== 'files')
{
throw new Exception('This class (' . __CLASS__ .') only works for file based session handling.');
}
// start session (it may already be started so suppress errors)
@session_start();
}
/**
* Retrieve a single instance of this class
*
* @usage
*
* $SessionData = FileSessionData::singleton();
*
*/
public static function singleton(array $args = array())
{
return parent::singleton(__CLASS__, $args);
}
/**
* Get the session Object for a session id
*
* @param string Session ID
*
* @return array|bool
*/
public function get($sess_id)
{
$data = $this->read($sess_id);
if ($data)
{
return self::decode($data);
}
return false;
}
/**
* Save the session Object for a session id
*
* @param string Session ID
* @param array Session Object
*
* @return Bool
*/
public function set($sess_id, array $sess)
{
$data = self::encode($sess);
return $this->write($sess_id, $data);
}
/**
* Unset a session
*
* @param string Session ID
*
* @return Bool
*/
public function un_set($sess_id)
{
return unlink($this->getPath($sess_id));
}
/**
* Returns if a session exists given it's ID
*
* @param string Session ID
*
* @return Bool
*/
public function is_set($sess_id)
{
return file_exists($this->getPath($sess_id));
}
/**
* Write raw session data to a session
*
* @param string Session Id
* @param string Session encoded data
*
* @return Bool Write result
*/
public function write($sess_id, $data)
{
return file_put_contents($this->getPath($sess_id), $data);
}
/**
* Read raw session data from a session
*
* @param string Session Id
*
* @return string Session Data
*/
public function read($sess_id)
{
return file_get_contents($this->getPath($sess_id));
}
/**
* Retrieve all session Ids
*
* @return array
*/
public function getIds()
{
if (!self::$sess_ids)
{
$files = $this->getFiles();
self::$sess_ids = array();
foreach($files as $file) {
// @todo use substr ?
$parts = explode('_', $file);
self::$sess_ids[] = array_pop($parts);
}
}
return self::$sess_ids;
}
/**
* Retrieve the file to the session given its id
*
* @param string Session ID
*
* @return string Session Path (Path may not exist)
*/
private function getPath($sess_id)
{
return $this->save_path . '/sess_' . $sess_id;
}
/**
* Retrieve the list of session files
*
* @return array
*/
private function getFiles()
{
if (!self::$sess_files)
{
self::$sess_files = glob($this->save_path . '/sess_*');
}
return self::$sess_files;
}
/**
* Decode/Unserialize encoded session data string
*
* @param string Session encoded data
*
* @return string Session Object
*/
public static function decode($data)
{
return parent::decode($data);
}
/**
* Encode/Serialize Object in session format
*
* @param array Session Object
*
* @return string Session encoded data
*/
public static function encode(array $sess)
{
return parent::encode($sess);
}
/**
* Maps isset() and unset()
*/
public function __call($method, $args)
{
if ($method == 'isset')
{
return call_user_func_array(array($this, 'is_set'), $args);
}
else if ($method == 'unset')
{
return call_user_func_array(array($this, 'un_set'), $args);
}
else
{
throw new Exception('Call to non-existant method ' . htmlentities($method) . ' of class ' . htmlentities(__CLASS__));
}
}
}
/**
* Class for retrieving session data
*
* Features:
* Retrieving of all session data saved by PHP, not just the current user
* Encoding and decoding in PHP session format (not serialize|unserialize)
*
* @author gabe@fijiwebdesign.com
* @link http://www.fijiwebdesign.com/
*
* This class must be implemented for each Session Handler as retrieving session data will be different for each
*
*/
abstract class AbstractSessionData
{
/**
* Retrieve a single instance of this class
*
* @usage
*
* $SessionData = AbstractSessionData::singleton('FileSessionData');
*
*/
public static function singleton($classname, array $args)
{
static $instance = array();
if (!isset($instance[$classname]))
{
$instance[$classname] = new $classname;
}
return $instance[$classname];
}
/**
* Get the session Object for a session id
*
* @param string Session ID
*
* @return array|Bool
*/
abstract public function get($sess_id);
/**
* Save the session Object for a session id
*
* @param string Session ID
* @param array Session Object
*
* @return Bool
*/
abstract public function set($sess_id, array $sess);
/**
* Unset a session
*
* @param string Session ID
*
* @return Bool
*/
abstract public function un_set($sess_id);
/**
* Returns if a session exists given it's ID
*
* @param string Session ID
*
* @return Bool
*/
abstract public function is_set($sess_id);
/**
* Write raw session data to a session
*
* @param string Session Id
* @param string Session encoded data
*
* @return Bool Write result
*/
abstract public function write($sess_id, $data);
/**
* Read raw session data from a session
*
* @param string Session Id
*
* @return string Session Data
*/
abstract public function read($sess_id);
/**
* Retrieve all session Ids
*
* @return array
*/
abstract public function getIds();
/**
* Decode/Unserialize encoded session data string
*
* @param string Session encoded data
*
* @return string Session Object
*/
public static function decode($data)
{
// save current session var and empty it
$sess_orig = $_SESSION;
$_SESSION = array();
// decode session data to $_SESSION
session_decode($data);
// restore original session
$sess = $_SESSION;
$_SESSION = $sess_orig;
return $sess;
}
/**
* Encode/Serialize Object in session format
*
* @param array Session Object
*
* @return string Session encoded data
*/
public static function encode(array $sess)
{
// save current session var
$sess_orig = $_SESSION;
$_SESSION = $sess;
// decode session data in $_SESSION
$data = session_encode();
// restore original session
$_SESSION = $sess_orig;
return $data;
}
}
// include the classes
require 'FileSessionData.php';
// instantiate the file session reader
$FileSession = FileSessionData::singleton();
// get all saved session ids
$sess_ids = $FileSession->getIds();
// loop through each session id on the server and show session data
foreach($sess_ids as $id)
{
// get the session data
if ($data = $FileSession->get($id))
{
// dump session array
dumper($data);
// dump serialized session
dumper(FileSessionData::encode($data));
exit; // lets limit to just one for testing
}
}
/**
* Dump utility
* @param Object
*/
function dumper($data)
{
echo '' . print_r($data, true) . '';
}
JavaScript regular expressions (browser) do not have a modifier allowing the dot (.) to match all characters including the newline like the ’s’ modifier does for PERL and PCRE in PHP.
However a cool tip I learnt just recently is that using a character class and it’s negated version will allow you to match all characters. Eg: /[\s\S]/g will match all characters in a JavaScript Regular Expression.
I used this trick in the ASCII to Hex conversion JavaScript code I posted a few days ago and thought to mention it.
Dear God,
I’m Sorry.
Be nice.
To Mommy and Daddy.
Amen.
I have a large collection of videos on my Windows PC. Before today, in order to watch the videos on my computer somewhere else in the house, we’d have to copy the movie to a USB stick and transfer it to the other computer.
Since this is an almost daily occurrence, and copying videos can take a while, I decided to look into streaming the videos over the Local network.
My first thought was to create a virtual host on my local Apache server, and have the videos streamed by Apache over HTTP. This worked reasonably well for a while, but after about 10 minutes or so the video started to lag on the other side. This also happened when I tried streaming the file via FTP, using Filezilla FTP server.
I also tried using Nginx which has an FLV streaming module. The videos on my PC are mostly .avi or .divx, so I’d have to transcode to FLV before hand in order to stream. I didn’t want to have to transcode each file to FLV, since it was already taking up a huge amount of space on my hard disk.
This whole time I was using VLC to play the videos. I had totally overlooked the fact that VLC was also a video streaming server. It turns out, VLC can transcode and stream at the same time (using FFMpeg internally), so you don’t need to transcode files before hand, and keep around multiple copies of the same file in different encodings.
Here is the article on streaming video with VLC that I followed. Pretty soon I had VLC on my PC streaming movies to multiple PCs and laptops on the local network. The videos playback can also be controlled from the streaming server, so I could start and play movies for my 2 and a half year old daughter Joana while doing my work.
The only problems with streaming with VLC is that you’ll have to mix and match video encodings and streaming protocols to figure out which works. For me, streaming H264 streamed over RTP seemed to work best. Edit: I somehow missed their documentation on supported streaming protocols.
You can also use the command line.
To open the command line on XP: Start -> Run -> type in “cmd” and click enter
On Vista: Start -> type “cmd” into the search box and click enter
In the command prompt, type: net view
For the list of IPs: arp -a
To get the IP of a computer given its name: ping <name>
To get the name of the current computer: hostname
Before trying out VLC, I was thinking of setting up Red5 to stream videos, since I have worked with it before to stream video and audio for XMPP (Instant Messaging), but since VLC does the job really well and is so easy to set up, I’m sticking to that for now.
I was woken up this morning by Vara, yelling into my ear. “There is a Tsunami warning for Fiji, wake up. Do you think it’s gonna come this far”?
We’re about a mile from the beach, but also at an elevation of about 50m or so. I replied, “No, not gonna come this far”. I was up all night on a project so this was not at the slightest bit interesting to me right now.
In my half alseep state however, each passing car started to sound like an approaching wave, crashing through the coconut trees and quickly tearing it’s way up the hill towards us. I decided to was time to wake up.
I started making my tea, listening to the radio. It was going on about the Tsunami warning and evacuations etc. There was a report about that the sea was retreating in the Yasawa’s. OK, sounds like this is a real disaster.
The first thing that came to mind was to see if I could get more up to date information online. I typed in http://twitter.com/ and did a search for “tsunami fiji“.
There were 2-3 updates every minute, and most of them stating the Tsunami warnings were already withdrawn. However, the radio was still going on with the warning. I didn’t really want to trust twitter solely, since most of it was just word of mouth.
I tried google, which would not have been useful in this situation a week ago. However, early this month they had implemented “search options” which allowed you to filter search results by date, showing the most recent results first.
Google proved to be up to date, with trusted information. Twitter had been just as, or maybe a few minutes ahead, but it took weeding through a few posts to finally get a trusted source.
It didn’t take long for Fiji Times to post an update on the cancelled Tsunami warning for Fiji. Which was immediately picked up by google, as well as twitter.
A few months ago I had the need to search for some very up to date information. Twitter provided the best source, in which google was quite useless. Now google seems to have noticed that they needed to provide realtime results. Twitter however still has the edge, with human interaction in near real-time and a wider range of resources. For example, if the Tsunami had actually hit, you could have watched it from around the world via Fiji Webcam link posted on twitter.
Now looking at this, I’m amazed at how close up to date information, especially those of large human interest such as disasters, is on the web now, mostly attributed to Twitter. Forget the radio, I’m doing a twitter search.
Allows you to convert to any base between 2 and 255, effectively using all the ASCII characters.
In order to convert very large numbers with arbitrary precision you’ll need the BCMath lib. Without BCMath the large numbers will not be converted correctly due to PHP not being able to do the arithmetic.
If you need to convert between bases 2-36, you can use the base_convert() function. However, converting to higher bases such as 255 has some benefits, such as “compressing” the characters.
You can successfully compress SHA1 from a 40 byte hex to a 20 byte string.
echo base255(base_convert(sha1('test'), 16, 10)));
Since there is no loss of data, it can be used as a lossless compression. Normal compression such as zlib won’t work on a SHA1 since there are no repeating patterns.
Here are some random JavaScript sinippets I wrote for bookmarks.
How they work is when you click the bookmark, the JavaScript is executed. So you can actually do a bit of programming inside a browser bookmark.
How to save JavaScript bookmarks:
javascript:window.location='http://www.google.com/translate_c?u='+window.location
javascript:void(alert(eval(prompt('Calculate:'))))
javascript:str='';i=0;c=prompt('Encode in Binary:');while(n=c.charCodeAt(i)){ b = '';while(n>0) { b = (n&1 ? '1' : '0')+b; n >>= 1; } i++;str+=b+' ' } void(alert(str))
Almost every software developer has used some sort of source code version control system. You’re probably familiar with the acronyms GIT, SVN or the now aging CVS. Here is a list of version control systems.
Version control is a form of concurrency control with the benefit of revisions. Todays major versioning systems work by creating a copy of a resource, and allowing a user to work on that copy. The user then checks their modified copy back to the central source code repository. If the copy at the repository has changed, then the user must merge the two changed copies together.
Since each user is working on a remote copy, there is no real time collaboration involved at all. Each user must edit their copy individually without input from the other users. The collaboration is somewhat chunked, instead of a smooth integration of two or more users inputs.
I’ve been waiting for the day when real time concurrency control is integrated with source code version control. Just lately Google launched Google Wave, which essentially implements real time concurrency control in document editing. A while before that, Appjet Launched their Etherpad product, which implemented real time concurrency control in document and JavaScript source code editing.
Neither of these currently implement source code version control. However, they are proofs that real time concurrency control can be achievable over the web (HTTP) using Operantional Transformation (OT).
Now the missing link is to tie together a real time concurrency control system, with a version control system. Imagine checking out a document with a number of colleges, editing it concurrently in real time, and checking it back into version control.
The model of source code versioning will change dramatically with integrated real-time concurrency control. Checking out a copy may be a thing of the past. You can just join a a group that is editing a live copy, and revisions can be saved automatically for individuals and/or the group as a whole.
Add your own thoughts here…
Appjet, a web based javascript application development platform, sent out an email to members today that they are closing down the service.
According to the email, they are closing their Appjet service because of the success of Etherpad - which is a real time document collaboration service that they built on Appjet. I think what they really mean is, appjet isn’t making any money and has become a liability. In that case, they just didn’t find a good way to capitalize on what they have, because it is quite awesome.
Appjet has been the only server side JavaScript development platform that offered a web based editor so you could create applications with just a connection to the internet, nothing else. There are many server side JavaScript alternatives, and many JavaScript Application development Platforms, none had the simplicity Appjet had. Nor is there a platform that encourages the sharing of libraries amongst developers like Appjet.
I have quite a few applications running on Appjet. One the fetches updates from freelance sites and posts it to a twitter account, freelance_jobs. Another pings websites and keeps a log of their uptime.Yet another acts as a proxy allowing RSS feeds to be fetched cross domain as a JSON callback. Theres even one that allows to to cheat at facebook’s wordtwist game by guessing all the possible combinations of words available for that round. There’s more then 10 of these apps I wrote and they were all hosted freely by Appjet. These were all developed in my spare time and at first I thought of them only as fun apps, but a few of them have become quite useful.
Now comes the porting of these apps to a new location. The great thing is that the appjet engine is available for download.
I’m considering installing this on my own server, or just rewriting everything in PHP.
I’ve just added the ability to parse mime mail from standard input into PHP Mime Mail Parser. This allows you to receive and parse email in PHP efficiently and effortlessly.
To pipe email to PHP, follow one of these articles:
Evolt - Incoming Mail and PHP
DevPapers - Incoming Mail and PHP
DevArticles - Incoming Mail and PHP
Then for your PHP code, get the PHP Mime Mail Parser, and use:
<?php
// include the mime-mail-parser class
require_once('MimeMailParser.class.php');
// instantiate
$Parser = new MimeMailParser();
// read the email from stdin
$Parser->setStream(STDIN);
// get the email parts
$to = $Parser->getHeader('to');
$delivered_to = $Parser->getHeader('delivered-to');
$from = $Parser->getHeader('from');
$subject = $Parser->getHeader('subject');
$text = $Parser->getMessageBody('text');
$html = $Parser->getMessageBody('html');
$attachments = $Parser->getAttachments();
?>
I’m back in Vuda. I just decided I couldn’t stay in Suva for another two days and came to the West early.
Today we just lounged under the coconut trees, while Joana explored the yard and did a bit of ‘vatatalo’ for the first time. Then in the evening we went down to the beach and Joana and I went for a swim.
It was a very fun day.
I brought my work PC over with me so I could so some work while here. Joana poured a cup of water over it. I have it drying out and I hope it is ok when I check it tomorrow morning.
I was reading the Qt blog’s on Webkit when I came aross this post on the chrome experiment Monster.
The experiment is written by Dean McNamee and is a JavaScript 3d rendering engine. There is a great article on it at the google code blog.
It renders a cube that turns into a sphere then a monster. All with just JavaScript, no Flash or other plugins.
I tried launching the demo (click to open in a new window) in Chrome, Safari and Firefox. Chrome was the only browser that handled the animation well. It didn’t even use more then a few MB of memory to do it. Safari climbed to about 200MB of memory and didn’t render the more intensive parts of the animation. Firefox was slow in rendering and also took up to 200MB of memory. This just shows how vastly superior Chrome’s Javascript engine (V8) is. You’d also have to take into account the implementation of the Canvas element, but the Javascript execution is what really matters.
The code for Monster isn’t released yet. Would be cool to play around with it when it is.
Very dreary weather this week. I just got back from the West which had nice sunshine. There is an aspect of dreary weather that might appeal to me, maybe when I’m 80 and can’t walk. I could just sit out on the front porch and watch the thin rain stream down from the sky like an endless gray mist, hour after hour. But not today. The rugby field is muddy and no one feels like playing. The warm blanket on my bed is inviting, but I know that as soon as you get in it will get too hot. We’ll you’d think we’d be used to this by now.
I think I’m going to go club that screaming dog tonight. It barks endlessly day after day, night after night. Poor thing actually, it is the owner’s fault. They keep it tied down all the time. Imagine if you were tied tree or post. You’d probably start barking after a few days.
We’ll right now I’m tied to this computer screen. Been on this for the last 8 hours and counting. I’m debating going out to play rugby but I don’t want to run 2 miles to find out the field is still muddy. Actually, I could use the exercise anyway. Right after I hit save.
Joana was very sick when I was in the West. Poor lil girl. It is quite disturbing to watch your child desperately sick. Makes me wish I had chosen to be a doctor instead of a code puncher. She’s well now and since then I’ve taken up reading medical sites in preparation for the next bout of sickness. I’d originally thought she was immune to sickness, 2 years without so much as a cough. We’ll at least now I know her immune system can handle whats thrown its way. She’s doing a lot better now by the way.
We’ll, for that rugby game. I’m off.
WP Cumulus Flash tag cloud by Roy Tanck requires Flash Player 9 or better.