« February 2004 | Inicio | April 2004 »

March 30, 2004

OT ( and rant ): Switching from Thunderbird to Outlook

After almost a year of being a happy Thunderbird user, I've been forced to switch back to Outlook. And it's been a real pain.

When I switched to Thunderbird, it took me five minutes to import my e-mails, addresses and rules from Outlook into Thunderbird. It was just a question of a few clicks.

But yesterday, everything was different. First, I couldn't find the "Export button" in Thunderbird. So, after reading the faq's, I discovered that the format of the mail folders is the standard Unix mail format ( "MBox" ), so that I could import my email from Outlook, using the "import from Eudora" assistant. Obviously, it didn't work. I constantly received error messages, telling me that the mail folders were in use ( when they weren't, I had all permissions for those folders, every Mozilla program was closed, ..)

So, back to google, I found an utility called MBox2eml, that allows to export mailboxes from the MBox format to eml ( the Outlook Express format ). This utility worked well, except for the fact that it failed when trying to transform a high number of items. So I was exporting my emails, 100 at a time.

Then, I exported my emails from Outlook Express to Outlook. Everything seemed to work right ( I have not checked the attachments yet ), but the whole process took me about three hours!!. Three hours to complete a process that should have been finished in only five minutes.

I'm not going to blame only Microsoft, but also Mozilla. I think it's obvious that switching to Outlook from Thunderbird should be as easy as the opposite. But, at least for me, it wasn't easy at all.

March 26, 2004

Is anybody using the mySQL panel?

About a month ago, we released an extension for the flash IDE, which contained a panel to browse a mySQL database, and a php class. ( you can read more about it here)

Well, there have been more than 1000 downloads yet, and we are a bit surprised, because we have not received any bug report, any report about installation problems,….

This has made us think what seems obvious: that nobody is using it.

Anyway, if you are using it, we'll like to know what do you think about it, what improvements, if any, you'd like to see in a future "release",….

March 25, 2004

Almost friday: a useless post

After a looooong day working on a class serializer, I needed to do something as light as possible. So here it is: a class that can be used as a timer.

You can execute any method, when a given time has passed, and after that reset the timer to use it as a timeout controller

It know that the actual architecture is based on events, but here you will also find a class to implement callbacks.

So, first of all, here's the callback implementation

class net.designnation.blog.Callback { private var callbackObjVal: Object; private var callbackMethodVal: String; public function Callback( objParam: Object, methodParam: String ) { this.callbackObj = objParam; this.callbackMethod = methodParam; } public function set callbackObj( objParam: Object ) { this.callbackObjVal= objParam; } public function get callbackObj( ): Object { return this.callbackObjVal; } public function set callbackMethod( methodParam: String ) { this.callbackMethodVal= methodParam; } public function get callbackMethod( ): String { return this.callbackMethodVal; } public function fire( parameter: Object ): Object { return this.callbackObjVal[ this.callbackMethodVal ]( parameter ); } }

The timer class is here:

import net.designnation.blog.* class net.designnation.blog.Timer { private static var FRAMERATE: Number = 12; private var timelineVal : MovieClip; private var clip : MovieClip; private var timeoutVal : Number; private var callBackVal : Callback; private var startedFlag : Boolean; private var actualCount : Number; function Timer( timelineParam: MovieClip, timeoutParam: Number, callBack: Callback ) { this.timeline = timelineParam; this.timeout = timeoutParam; this.callback = callBack; } public function set timeline( value: MovieClip ) { this.timelineVal = value; } public function set timeout( value: Number ) { this.timeoutVal = value* FRAMERATE/ 1000; } public function set callback( value: Callback ) { this.callBackVal = value; } public function init( ) { this.actualCount = 0; this.clip = this.timelineVal.createEmptyMovieClip( "clip", this.timelineVal.getNextHighestDepth( ) ); this.clip[ "owner" ] = this; this.clip.onEnterFrame = function( ) { if ( this[ "owner" ].startedFlag ) { if ( this[ "owner" ].actualCount< this[ "owner" ].timeoutVal ) { this[ "owner" ].actualCount++; } else { this[ "owner" ].onFinish( ); } } }; } public function start( ) { this.startedFlag = true; } public function stop( ) { this.startedFlag = false; } public function reset( ) { this.actualCount = 0; this.startedFlag = true; } public function resetTo( newTimeOut: Number ) { this.actualCount = 0; this.timeout = newTimeOut; this.startedFlag = true; } public function remove( ) { this.clip.removeMovieClip( ); delete this.clip; } private function onFinish( ) { this.startedFlag = false; this.actualCount = 0; this.callBackVal.fire( { reqTime: this.timeoutVal } ); } }

And finally, a class to test everything

import net.designnation.blog.* class net.designnation.blog.TimerTest { private var timeline: MovieClip; private var time : Number; private var theTimer: Timer; function TimerTest( timelineParam: MovieClip, timeoutParam: Number ) { this.timeline = timelineParam; this.time = timeoutParam; this.init( ); } public function init( ) { this.theTimer = new Timer( this.timeline, this.time, new Callback( this, "timeOutCallback" ) ); this.theTimer.init( ); this.theTimer.start( ); } public function timeOutCallback( ) { trace( "Time goes by..." ); /// For instance: this.theTimer.resetTo( this.time ); } }

And finally, we have the following code in a frame:

import net.designnation.blog.* var theTest: TimerTest = new TimerTest( this, 1000 );

Happy friday....

March 23, 2004

OT: new CSS

Finally, we've gathered the time and courage to change this CSS. Here's the result.

We've tested it on IE, Firefox and Opera ( Win ), but haven't tested it on OSX, although we've been told that it seems right.

Anyway, if you see any bug, or feel that there's something hard to read, please tell us.

And just for your information, the header pictures have been taken by us. They are part of what we see every day.

March 20, 2004

Developing an AS2 framework

For the last two months, I've been working on a huge AS2 framework, as part of a two year long project that includes the development of about two hundred games, apart from an e-learning platform.

This framework will be the base to develop those flash games. In fact, we are developing some simple games, with simple physics, in four ours.

We are basing our development in design patterns, mostly the state pattern, and also a lot of MVC, Singleton, Decorator and Facade patterns. We also are implementing all our backend in webservices.

I didn't find easy to adapt my coding practices and knowledge from my pure scripting background to such an abstract way of coding. But now, I must admit that not only the code will be really easy to maintain, but the development proccess is shorter and easier.

And, also, I've found that, apart from some problems with the compiler, the flash player ( or virtual machine ) has proved to be very reliable. Some of the games we've developed yet involve more than 200 classes, and the player has been managing them perfectly.

So, in fact, learning OOP is worth the effort ( and, at the end, this is flash, so there always comes the moment when you must / can apply all the things that really make me love this language: the flexibility, the ability to modify some of its core poperties, the procedural animations,....... ;P )

March 11, 2004

My coding standards

I've read about coding standards, or coding best practices recently ( like this one from Dominick ). Well, here are my coding standards:

First of all, code should be self-explanatory. So, in my place of work we don't write too many comments ( in fact we never write comments, although we write class diagrams, and a lot of UML ).

Here you can see an example class. I've commented it just to avoid a longer explanation:

/* The class name is cualified with the project name ( pn ) This class extends another class */ class net.designnation.pnTestClass extends pnSuperClass { /* Here are the private vars. They will be accesed through getter/setters so their name ends with "Val" */ private var strVal : String; private var boolVal : String; private var mcVal : MovieClip private var arg : Number; /* Then, you could find the class constructor */ function pnTestClass( argParam: Number ) { this.arg = argParam } /* Then the getter and setters We only define the methods that are needed to access the property from outside the class */ function set str( value: String ) { this.strVal = value; } function get str( ): String { return this.strVal; } /* Here we only define the setter. That's all we need */ function set bool( value: Param ) { this.boolVal = value; } function set mc( value: MovieClip ) { this.mcVal = value; } //The private methods private function privateMethod( Void ): Void { } // The rest of public and interface methods public function publicMethod( Void ): Boolean { //We are accessing a private property from //inside the class, so we don't need a getter var returnVal: Boolean = false; if ( this.boolVal ) { returnVal = true; } return returnVal; } /* And finally, all the callbacks and listeners */ public function onKeyUp( ) { } }

Some important points: We allways use the prefix "this.", so it's easier to see when a method or a property belongs to the class. If there is no "this" prefix, it means that it's a method or property of the superclass

Spacing is very important for us. It makes our code easier to read, and to understand. We don't mind about the code size, there are always a lot of whitelines.

Brackets are always paired. And there is also a white space between operators.

Also, all methods that return a value must have only one return point.

Hope it helps. Sure it does for us.

Terrorist attack in Madrid

Sorry, but I'm too nervous. There have been at least three explosions in Madrid, I've heard two of them from my house.

I'm going out to try to help, if it's possible. This is quite sad, and extremely unfair. We don't deserve this.

Sorry for the noise.

March 09, 2004

Hello, MXNA!

We've just recieved an e-mail telling us that this blog will be aggregated by MXNA. We feel really proud, and a bit scared, because of all the people that will read our posts from now on.

Anyway, we just wanted to say hi. We'll be glad to receive your comments, suggestions, rants, ....

And we hope you could find some useful information around here.

And last, but not least, a big "thank you" to the people at MXNA.

March 01, 2004

Design patterns: MVC ( the correct implementation? )

Yesterday, Darron Schall pointed that my implementation wasn't really a Model-View-Controller, because the view should listen to the events boradcasted by the model.

The fact is that I've been using the implementation I posted yesterday for so long, that I forgot that it wasn't correct. So, I've refactored my code, and here are the results.

Now, the controller aggregates an instance of the view, and and instance of the model. The view listens to the model's events, and uses the controller to access the model.

I'm not really sure about my code, I don't know if this is the best way to implement this pattern, so I'll be glad to hear any suggestions.

Anyway, you can download the source code here

Design patterns: almost MVC ( model-view-controller )

We'll build a reverse clock. The clock starts when the stage is clicked, and can be stopped clicking the stage again.

To read a really good article about what the MVC pattern is, click here

Basically, we'll try to break our application into three layers. The model (application data and logic ), the view ( the interface) and the controller ( responsible of updating the data when the interface changes, and responsible of updating the interface when the data changes ).

In this example, the model is a AS2 class, that will count the remaining time. With every second, this class fires an event, that is listened by the controller, that will update the view, which is a textfield that shows the remaining time. When we click the stage, the view tells de controller to change it's state, and the controller will tells the model to do so ( to stop if it was running, or to run if it was stopped ).

First, you must be sure that swf loading order ( File-> Publish settings-> swf-> loading order ) is set to "down to up". So, the controller will be created on the first frame of the first layer, and the view will be created in the first frame of the second layer.

To create the controller instance:

import net.designnation.patterns.* var myController: controller = new controller( this ); myController.init( 60 );

The controller aggragates an instance of the model:

public function init( time: Number ) { this.myClock = new clock( this.timeline, time ); this.myClock.addEventListener( "endOfTime", this ); this.myClock.addEventListener( "updateTime", this ); this.myClock.init( ); }

So, when the clock instance is created, it receives two parameters, a reference to _root, and the total time, so:

public function init( ) { this.clockClip = timeline.createEmptyMovieClip( "empty", this.timeline.getNextHighestDepth( ) ); this.clockClip[ "owner" ] = this; this.clockClip.onEnterFrame = function ( ) { if ( this[ "owner" ].workingFlag ) { if ( this[ "owner" ].actualTime>= 1 ) { this[ "owner" ].actualTime--; if ( this[ "owner" ].actualTime % FRAMERATE == 0 ) { this[ "owner" ].dispatchTime( this[ "owner"].actualTime ); } } else { this[ "owner" ].dispatchTime( ); delete this.onEnterFrame; } } } }

When I write

this.clockClip[ "owner" ] = this;

it's exactly the same than:

this.clockClip.owner = this;

The brackets just help me see that it's a dynamically created variable.

When a second has passed, an event is fired:

private function dispatchTime( actualTime: Number ) { if ( actualTime == null ) { var event = "endOfTime"; } else { var event = "updateTime"; } this.dispatchEvent( {type: event, target: this, time: ( actualTime/ FRAMERATE ) } ); }

The controller is registered as a clock listener so the following method is executed:

public function updateTime( arg: Object ) { this.timeline.clock.text = arg.time; }

so the view is updated.

When we click the stage:

this.onMouseUp = function( ) { myController.changeClockState( "clock" ); }

So, in the controller:

public function changeClockState( ) { this.myClock.changeClockState( ); }

And finally,

public function changeClockState( ) { this.workingFlag = !this.workingFlag; }

So, every message between the view and the model is carried by the controller. So the graphics and the application logic are separated, so our application will be easier to maintain, our code will be easier to understand....

And again, we've mixed AS2 and AS1 code.

Download the source files here