Yet more to consider:
http://stackoverflow.com/questions/1242060/symfony-vs-cakephp
Symfony is another contender.
Showing posts with label flash framework. Show all posts
Showing posts with label flash framework. Show all posts
Thursday, February 10, 2011
MVC PHP Frameworks Evaluated
PHP frameworks are my current focus, particularly CodeIgniter. I have extensive experience with AS MVC frameworks, e.g. Cairngorm, RobotLegs, and Mate. Following a recent project, my thoughts on PHP frameworks are starting to crystallize. Here incidentally is IMO one of the best summaries on CI from the community at large, reposted courtesy of Action on this stackoverflow post :
As you can see, it is a comparison of CI with another framework, CakePHP, which is now on my shortlist to test out. Here is a Google Trends search of the relative trendiness of these two open-source frameworks (update: now three OS frameworks with symfony).
http://www.google.com/trends?q=codeigniter%2C+cakephp%2C+symfony&ctab=0&geo=all&date=all&sort=0
CakePHP has an earlier footprint. Next, I will examine CakePHP support of php5. I'm curious to know of any more advanced, more OO and generally more hurricane-nestled-in-a-typhoon-wrapped-in-a-tornado PHP frameworks out there. I would prefer a stricter MVC pattern with a higher degree of decoupling.
CodeIgniter is, without a doubt, the most well-documented and approachable PHP MVC framework out there. CakePHP's documentation is also very good, but the learning curve is slightly higher.In conclusion, if you want a fast, flexible, well-documented framework, and don't mind writing extra code and relying on 3rd party libraries, go with CodeIgniter. If you want a powerful, feature-rich framework that does most of the heavy lifting through automation, and you don't mind having to follow strict conventions, go with CakePHP.
- CodeIgniter's models are optional and serve no function other than code separation. There's no integrated CRUD and its "Active Record" class is really just an alternative SQL syntax. It also doesn't support table associations. So, you will be building many large queries essentially from scratch. CakePHP's models are far more advanced and similar to those in Ruby on Rails. It supports table associations, has integrated CRUD, and behaviors. In addition, CakePHP has command line tools (Bake) that allow you to generate all the code for basic CRUD operations. Tweak a few things here and there and you've got a working prototype in minutes.
- CodeIgniter lacks some essential libraries that are needed in most applications (i.e. Authentication and ACL). You will need to rely on 3rd party libraries in many of your applications. CakePHP has integrated Auth and ACL, but both frameworks integrate with 3rd party libraries easily.
- Since CodeIgniter lacks much of the automation that CakePHP brings, there are no strict conventions to follow (this can be viewed as good or bad). This makes CodeIgniter a more flexible framework. Furthermore, its lack of features and automation do give it an advantage when it comes to speed. CodeIgniter is one of the fastest PHP MVC frameworks out there. That said, the framework is rarely the bottleneck in your in application...and you should be choosing a framework based on productivity, not its execution speed.
- Both frameworks have large and helpful communities. CodeIgniter has their official forums and an IRC channel. CakePHP has a google group and an active IRC channel. CakePHP is currently the most popular PHP MVC framework with the largest community behind it.
http://www.google.com/trends?q=codeigniter%2C+cakephp%2C+symfony&ctab=0&geo=all&date=all&sort=0
CakePHP has an earlier footprint. Next, I will examine CakePHP support of php5. I'm curious to know of any more advanced, more OO and generally more hurricane-nestled-in-a-typhoon-wrapped-in-a-tornado PHP frameworks out there. I would prefer a stricter MVC pattern with a higher degree of decoupling.
Labels:
cakephp,
flash framework,
MVC,
php,
stackoverflow
Thursday, December 9, 2010
AS3 Command Pattern for Rapid Asset Development
You know those little modular swf projects where you just program in some basic functionality in lieu of using the timeline? Well, I have had a few of those lately, so I made a little module manager.
It's based upon a useful tutorial I ran across and tweaked a bit. I created a google code repository to host the result, called as3minimalcommandpattern.
See this demo which uses only this library. All the code from the demo is pasted below ( the demo can be found with source in the repository).
The demo consists of the document class and as many 'scenes' as are required for the project. A scene in this sense is simply a way to encapsulate an intro-outro sequence. It's good for doing the monotonous work for you so you can focus on integrating advanced features.
It's based upon a useful tutorial I ran across and tweaked a bit. I created a google code repository to host the result, called as3minimalcommandpattern.
See this demo which uses only this library. All the code from the demo is pasted below ( the demo can be found with source in the repository).
The demo consists of the document class and as many 'scenes' as are required for the project. A scene in this sense is simply a way to encapsulate an intro-outro sequence. It's good for doing the monotonous work for you so you can focus on integrating advanced features.
Document Class:
package
{
import com.bluediesel.utils.managers.scenemanager.SceneManager;
import flash.display.MovieClip;
import scenes.*;
public class Main extends MovieClip
{
public function Main()
{
var sceneManager:SceneManager = new SceneManager();
sceneManager.setScene(new IntroScene(this));
}
}
}
IntroScene (Setup the UI):
package scenes
{
import com.bluediesel.utils.managers.scenemanager.commands.*;
import com.bluediesel.utils.managers.scenemanager.commands.greensock.*;
import com.bluediesel.utils.managers.scenemanager.scenes.*;
import com.greensock.plugins.*;
import fl.transitions.easing.Strong;
public class IntroScene extends AbstractScene implements IScene
{
public function IntroScene(c:Object) {
TweenPlugin.activate([AutoAlphaPlugin]);
super(c);
}
override public function createIntroCommand():Command
{
return new SerialCommand( 0.1,
new TweenMaxTo ( c.backgroundMC, 0.1, { blurFilter:{blurX:20, blurY:20} } ),
new TweenMaxTo ( c.backgroundMC, 0.4, { autoAlpha:1, blurFilter:{blurX:0, blurY:0} } ),
new ParallelCommand( 0,
new TweenMaxTo( [c.uiTopBanner, c.uiBottomBanner, c.buttonPrevious, c.buttonNext], 0.2, { autoAlpha:1 } ),
new TweenMaxFrom( [c.uiTopBanner, c.uiBottomBanner, c.buttonPrevious, c.buttonNext], 0.3, { y:500, easing:Strong.easeOut } )
),
new TweenMaxTo ( [c.appTitle, c.clickForSoundText], 0.2, { autoAlpha:1 } )
);
}
override public function onSceneSet():void {
sceneManager.setScene( new Scene01(c) );
}
}
}
Scene01 (Intro-Outro Sheep):
package scenes
{
import com.bluediesel.utils.managers.scenemanager.commands.*;
import com.bluediesel.utils.managers.scenemanager.commands.events.*;
import com.bluediesel.utils.managers.scenemanager.commands.greensock.*;
import com.bluediesel.utils.managers.scenemanager.commands.utils.SetProperties;
import com.bluediesel.utils.managers.scenemanager.scenes.*;
import fl.transitions.easing.Strong;
import flash.events.MouseEvent;
import flash.media.*;
public class Scene01 extends AbstractScene implements IScene
{
public function Scene01(c:Object)
{
super(c);
}
override public function createIntroCommand():Command
{
return new SerialCommand(0,
new TweenMaxTo ( c.sheepTitle, 0.2, { autoAlpha:1 } ),
new TweenMaxTo ( c.sheepMC, 0.2, { autoAlpha:1 } ),
new TweenMaxTo ( c.bodyCopyBG, 0.2, { height:231, width:470, autoAlpha:1, easing:Strong.easeOut } ),
new TweenMaxTo ( c.sheepBodyCopy, 0.2, { autoAlpha:1 } ),
new SetProperties ( [c.buttonPrevious, c.buttonNext, c.sheepMC, c.horseMC, c.pigMC], {buttonMode:true, useHandCursor:true} ),
new AddEventListener( c.sheepMC, MouseEvent.MOUSE_DOWN, playNoise ),
new AddEventListener( c.buttonPrevious, MouseEvent.MOUSE_DOWN, handlePrevious ),
new AddEventListener( c.buttonNext, MouseEvent.MOUSE_DOWN, handleNext )
);
}
override public function createOutroCommand():Command
{
return new SerialCommand(0,
new RemoveEventListener( c.sheepMC, MouseEvent.MOUSE_DOWN, playNoise ),
new RemoveEventListener( c.buttonPrevious, MouseEvent.MOUSE_DOWN, handlePrevious ),
new RemoveEventListener( c.buttonNext, MouseEvent.MOUSE_DOWN, handleNext ),
new TweenMaxTo ( c.sheepBodyCopy, 0.1, { autoAlpha:0 } ),
new TweenMaxTo ( c.bodyCopyBG, 0.1, { height:0, width:0, autoAlpha:0, easing:Strong.easeOut } ),
new TweenMaxTo ( c.sheepMC, 0.1, { autoAlpha:0 } ),
new TweenMaxTo ( c.sheepTitle, 0.1, { autoAlpha:0 } )
);
}
override public function onSceneSet():void
{
//TODO: implement function
}
/* CUSTOM METHODS */
private function handlePrevious(e:MouseEvent):void
{
trace ("Already At Beginning");
//sceneManager.setScene( new IntroScene( c ) );
}
private function handleNext(e:MouseEvent):void
{
sceneManager.setScene( new Scene02 ( c ) );
}
private function playNoise(e:MouseEvent):void{
var soundChannel:SoundChannel = new SoundChannel();
soundChannel = new SheepNoise().play();
}
/* END CUSTOM METHODS */
}
}
Scene02 (Intro-Outro Horse):
package scenes
{
import com.bluediesel.utils.managers.scenemanager.commands.*;
import com.bluediesel.utils.managers.scenemanager.commands.events.*;
import com.bluediesel.utils.managers.scenemanager.commands.greensock.*;
import com.bluediesel.utils.managers.scenemanager.scenes.*;
import fl.transitions.easing.Strong;
import flash.events.MouseEvent;
import flash.media.*;
public class Scene02 extends AbstractScene implements IScene
{
public function Scene02(c:Object)
{
super(c);
}
override public function createIntroCommand():Command
{
return new SerialCommand(0,
new TweenMaxTo( c.horseTitle, 0.2, { autoAlpha:1 } ),
new TweenMaxTo( c.horseMC, 0.2, { autoAlpha:1 } ),
new TweenMaxTo ( c.bodyCopyBG, 0.2, { height:231, width:470, autoAlpha:1, easing:Strong.easeOut } ),
new TweenMaxTo( c.horseBodyCopy, 0.2, { autoAlpha:1 } ),
new AddEventListener( c.horseMC, MouseEvent.MOUSE_DOWN, playNoise ),
new AddEventListener( c.buttonPrevious, MouseEvent.MOUSE_DOWN, handlePrevious ),
new AddEventListener( c.buttonNext, MouseEvent.MOUSE_DOWN, handleNext )
);
}
override public function createOutroCommand():Command
{
return new SerialCommand(0,
new RemoveEventListener( c.horseMC, MouseEvent.MOUSE_DOWN, playNoise ),
new RemoveEventListener( c.buttonPrevious, MouseEvent.MOUSE_DOWN, handlePrevious ),
new RemoveEventListener( c.buttonNext, MouseEvent.MOUSE_DOWN, handleNext ),
new TweenMaxTo ( c.horseBodyCopy, 0.1, { autoAlpha:0 } ),
new TweenMaxTo ( c.bodyCopyBG, 0.1, { height:0, width:0, autoAlpha:0, easing:Strong.easeOut } ),
new TweenMaxTo ( c.horseMC, 0.1, { autoAlpha:0 } ),
new TweenMaxTo ( c.horseTitle, 0.1, { autoAlpha:0 } )
);
}
override public function onSceneSet():void
{
}
/* CUSTOM METHODS */
private function handlePrevious(e:MouseEvent):void
{
sceneManager.setScene( new Scene01 ( c ) );
}
private function handleNext(e:MouseEvent):void
{
sceneManager.setScene( new Scene03 ( c ) );
}
private function playNoise(e:MouseEvent):void{
var soundChannel:SoundChannel = new SoundChannel();
soundChannel = new HorseNoise().play();
}
/* END CUSTOM METHODS */
}
}
Scene03 (Intro-Outro Pig):
package scenesIf you notice the repeating signature of a Scene class, the timeline functionality is controlled by createIntroCommand and createOutroCommand. Below those functions are any custom methods that the scene needs. There are ways this could be further packaged up, like an external class that contains all the helper functions. For now, this is a way to build a quick linear module or application without resorting to the timeline or to a more intensive solution such as a fully-fledged framework.
{
import com.bluediesel.utils.managers.scenemanager.commands.*;
import com.bluediesel.utils.managers.scenemanager.commands.events.*;
import com.bluediesel.utils.managers.scenemanager.commands.greensock.*;
import com.bluediesel.utils.managers.scenemanager.scenes.*;
import fl.transitions.easing.Strong;
import flash.events.MouseEvent;
import flash.media.*;
public class Scene03 extends AbstractScene implements IScene
{
public function Scene03(c:Object)
{
super(c);
}
override public function createIntroCommand():Command
{
return new SerialCommand(0,
new TweenMaxTo( c.pigTitle, 0.2, { autoAlpha:1 } ),
new TweenMaxTo( c.pigMC, 0.2, { autoAlpha:1 } ),
new TweenMaxTo ( c.bodyCopyBG, 0.2, { height:231, width:470, autoAlpha:1, easing:Strong.easeOut } ),
new TweenMaxTo( c.pigBodyCopy, 0.2, { autoAlpha:1 } ),
new AddEventListener( c.pigMC, MouseEvent.MOUSE_DOWN, playNoise ),
new AddEventListener( c.buttonPrevious, MouseEvent.MOUSE_DOWN, handlePrevious )
);
}
override public function createOutroCommand():Command
{
return new SerialCommand(0,
new RemoveEventListener( c.pigMC, MouseEvent.MOUSE_DOWN, playNoise ),
new RemoveEventListener( c.buttonPrevious, MouseEvent.MOUSE_DOWN, handlePrevious ),
new TweenMaxTo( c.pigBodyCopy, 0.1, { autoAlpha:0 } ),
new TweenMaxTo( c.bodyCopyBG, 0.1, { height:0, width:0, autoAlpha:0, easing:Strong.easeOut } ),
new TweenMaxTo( c.pigMC, 0.1, { autoAlpha:0 } ),
new TweenMaxTo( c.pigTitle, 0.1, { autoAlpha:0 } )
);
}
/* CUSTOM METHODS */
private function handlePrevious(e:MouseEvent):void
{
sceneManager.setScene( new Scene02 ( c ) );
}
private function playNoise(e:MouseEvent):void{
var soundChannel:SoundChannel = new SoundChannel();
soundChannel = new PigNoise().play();
}
/* END CUSTOM METHODS */
}
}
Tuesday, June 15, 2010
RobotLegs in Flash CS4
Robotlegs is an as3 framework that has been gaining traction in the dev community lately. You can find a repository for it on github, and the demos make for a good test drive. It works in Flex or Flash with proper respective configuration.
Robotlegs demos will work fine in Flash CS4 as long as you do the following:
Robotlegs demos will work fine in Flash CS4 as long as you do the following:
- Opt-Shift-F12 to open publish settings > click AS3 settings near the top > Library Path: add the bin directory that contains the robotlegs swc
- In the main Publish Settings panel, be sure to check Export SWC
- Use the root of the demo folder as your document root directory.
Subscribe to:
Posts (Atom)