The Next Step in 
AS3 Framework 
Evolution
02.2013
About me
Senior AS3 Developer
Working with Flash from 2001
Author of open source AS3 framework – mvcExpress
Twitter : @Der...
About this presentation
● AS3 framework evolution
● Modular programming in mvcExpress
● mvcExpress live
AS3 framework 
evolution
AS3 framework history
●
PureMVC (2006)
●
Cairngorm (2007?) [flex only]
●
Springactionscript (2007)
●
Parsley(2008)
●
Mate(...
AS3 framework history
●
PureMVC (2006)
●
Cairngorm (2007?) [flex only]
●
Springactionscript (2007)
●
Parsley(2008)
●
Mate(...
PureMVC
●
Organize your code is small units
●
Let those units communication
●
Standardize your code
●
Focus on app instead...
The good The bad
robotlegs
●
All PureMVC goodness.
●
Removed most boilerplate
code
●
Introduces dependency
injection
●
Hur...
The good The bad
robotlegs 2 (beta)
●
Highly configurable
●
Modular
●
Guards ,hooks, rules.
●
Adds some boilerplate code
●...
The good The bad
mvcExpress
●
All PureMVC and robotlegs
goodness.
●
Focus on modular
development
●
Simplifies code even mo...
package {
public class PureMvcMediator extends Mediator implements IMediator {
public static const NAME:String = "PureMvcM...
package {
public class PureMvcMediator extends Mediator implements IMediator {
public static const NAME:String = "PureMvcM...
package {
public class PureMvcMediator extends Mediator implements IMediator {
public static const NAME:String = "PureMvcM...
package {
public class PureMvcMediator extends Mediator implements IMediator {
public static const NAME:String = "PureMvcM...
package {
public class MvcExpressMediator extends Mediator {
[Inject]
public var view:ViewComponent;
override public funct...
package {
public class MvcExpressMediator extends Mediator {
[Inject]
public var view:ViewComponent;
override public funct...
package {
public class MvcExpressMediator extends Mediator {
[Inject]
public var view:ViewComponent;
override public funct...
package {
public class MvcExpressMediator extends Mediator {
[Inject]
public var view:ViewComponent;
override public funct...
Speed test data
mvcExpress pureMVC robotlegs robotlegs 2
Command creation and execution: 0.00087 0.00219 0.00866 0.01894
P...
Command runs /1ms
pureMVC robotlegs robotlegs 2 mvcExpress mvcExpress
(pooled)
Command with nothing: 495.0 109.3 55.3 1010...
Command runs /1ms
pureMVC robotlegs robotlegs 2 mvcExpress mvcExpress
(pooled)
Command with nothing: 495.0 109.3 55.3 1010...
Command runs /1ms
pureMVC robotlegs robotlegs 2 mvcExpress mvcExpress
(pooled)
Command with nothing: 495.0 109.3 55.3 1010...
Command runs /1ms
pureMVC robotlegs robotlegs 2 mvcExpress mvcExpress
(pooled)
Command with nothing: 495.0 109.3 55.3 1010...
Command runs /1ms
pureMVC robotlegs robotlegs 2 mvcExpress mvcExpress
(pooled)
Command with nothing: 495.0 109.3 55.3 1010...
Command runs /1ms
pureMVC robotlegs robotlegs 2 mvcExpress mvcExpress
(pooled)
Command with nothing: 495.0 109.3 55.3 1010...
Communication performance
Direct communication:
Indirect communication:
Communication performance
Direct communication:
Indirect communication:
Overview
Overview
Overview
Modular programming in 
mvcExpress
Modular programming
features
●
Aggregation
●
Communication
●
Dependencies(data)
●
Permission control (v1.4)
Aggregation
mediatorMap.mediate(moduleB);
var moduleB:ModuleB = new ModuleB();
view.addChild(moduleB);
Module communication
Module communication
Module communication
sendScopeMessage("scopeName", "messageType", new ParamObject());
addScopeHandler("scopeName", "messag...
Module data sharing
(data dependencies)
Module data sharing
(data dependencies)
Module data sharing
(data dependencies)
proxyMap.scopeMap("scopeName", myProxyObject);
[Inject(scope="scopeName")]
public ...
Scope permissions
registerScope(scopeName:String,
messageSending:Boolean = true,
messageReceiving:Boolean = true,
proxieMa...
Dungeon viewer example
Modular programming
pitfalls
●
Planning is needed
●
Good module should be able to stand
as application on its own
– Chat w...
MvcExpress live
mvcExpress live
●
mvcExpress live = mvcExpress + game engine
– Continuous logic execution
– Dynamic animations
– Breaking ...
mvcExress live diagram
mvcExress live diagram
mvcExress live diagram
mvcExress live diagram
mvcExress live diagram
mvcExress live diagram
mvcExress live diagram
Process examplepackage com.mindscriptact.testProject.engine {
public class GameEngineProcess extends Process {
override pr...
Task example
package com.mindscriptact.testProject.engine.tasks {
public class ShowEnemiesTask extends Task {
[Inject(cons...
mvcExpress live testing
package com.mindscriptact.testProject.engine.tasks {
public class ShowEnemiesTask extends Task {
[...
Process run speed
●
Best case:
– Runs 1000000 empty Task's in 17 ms
– 58823 empty tasks in 1 ms
●
Worst case:
– 13300 empt...
MvcExpress live overview
●
Designed with games in mind but can be used in any
application than has repeating logic to run....
On learning 
curve
On learning curve
●
MVC framework initial learning curve is steep...
●
But if you learned one – learning another is easy!
...
MvcExpress logger
Links
http://mvcexpress.org/
https://github.com/MindScriptAct/mvcExpress-framework
https://github.com/MindScriptAct/mvcExp...
Upcoming SlideShare
Loading in …5
×

The Next Step in AS3 Framework Evolution - FITC Amsterdam 2013

13,702
-1

Published on

Join Raimundas (author of mvcExpress frameworks) as he presents his vision of next step in AS3 MVC framework evolution.

Writing maintainable software fast – was never a trivial task, but MVC frameworks are here to help us! In this session you will see short reminder of MVC framework history, comparison of coding convenience and performance benchmark results for PureMVC, robotlegs and mvcExpress frameworks.

For those who does not enjoy seeing code or statistic tables as much as running applications, Raimundas will show dungeon editor/crawler to demonstrate mvcExpress modular programming features, designed to save even more time and headaches while developing games and applications.

Published in: Technology, Education
5 Comments
6 Likes
Statistics
Notes
No Downloads
Views
Total Views
13,702
On Slideshare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
27
Comments
5
Likes
6
Embeds 0
No embeds

No notes for slide

The Next Step in AS3 Framework Evolution - FITC Amsterdam 2013

  1. 1. The Next Step in  AS3 Framework  Evolution 02.2013
  2. 2. About me Senior AS3 Developer Working with Flash from 2001 Author of open source AS3 framework – mvcExpress Twitter : @Deril
  3. 3. About this presentation ● AS3 framework evolution ● Modular programming in mvcExpress ● mvcExpress live
  4. 4. AS3 framework  evolution
  5. 5. AS3 framework history ● PureMVC (2006) ● Cairngorm (2007?) [flex only] ● Springactionscript (2007) ● Parsley(2008) ● Mate(2008) [flex only] ● Robotlegs(2009) ● Swiz(2009) [flex only] ● MvcExpress(2012) ● Robotlegs 2 (2012) (in beta) (ActionScript 3.0 released in 2006)
  6. 6. AS3 framework history ● PureMVC (2006) ● Cairngorm (2007?) [flex only] ● Springactionscript (2007) ● Parsley(2008) ● Mate(2008) [flex only] ● Robotlegs(2009) ● Swiz(2009) [flex only] ● MvcExpress(2012) ● Robotlegs 2 (2012) (in beta) (ActionScript 3.0 released in 2006)
  7. 7. PureMVC ● Organize your code is small units ● Let those units communication ● Standardize your code ● Focus on app instead of architecture ● Ported to many languages ● Slightly hurts performance ● Built on static classes ● Lot of boilerplate code Can't it be done simpler? The good The bad
  8. 8. The good The bad robotlegs ● All PureMVC goodness. ● Removed most boilerplate code ● Introduces dependency injection ● Hurts performance a lot! Can't it be done simpler... and run fast?
  9. 9. The good The bad robotlegs 2 (beta) ● Highly configurable ● Modular ● Guards ,hooks, rules. ● Adds some boilerplate code ● Code less standardized ● Hurts performance a lot (and more) I meant faster! Not slower...
  10. 10. The good The bad mvcExpress ● All PureMVC and robotlegs goodness. ● Focus on modular development ● Simplifies code even more ● Hurts performance the least ● Young framework Simplest and fastest MVC framework!
  11. 11. package { public class PureMvcMediator extends Mediator implements IMediator { public static const NAME:String = "PureMvcMediator"; public function PureMvcMediator(initViewComponent:ViewComponent) { super(NAME, initViewComponent); } // cast view for convenient local use. public function get view():ViewComponent { return super.getViewComponent() as ViewComponent; } // listen for framework notices override public function listNotificationInterests():Array { return [ // DataNote.STUFF_DONE // ]; } // handle framework events override public function handleNotification(notice:INotification):void { switch (notice.getName()) { case DataNote.STUFF_DONE: // do stuff… break; } }} pureMVC mediator
  12. 12. package { public class PureMvcMediator extends Mediator implements IMediator { public static const NAME:String = "PureMvcMediator"; public function PureMvcMediator(initViewComponent:ViewComponent) { super(NAME, initViewComponent); } // cast view for convenient local use. public function get view():ViewComponent { return super.getViewComponent() as ViewComponent; } // listen for framework notices override public function listNotificationInterests():Array { return [ // DataNote.STUFF_DONE // ]; } // handle framework events override public function handleNotification(notice:INotification):void { switch (notice.getName()) { case DataNote.STUFF_DONE: // do stuff… break; } }} pureMVC mediator
  13. 13. package { public class PureMvcMediator extends Mediator implements IMediator { public static const NAME:String = "PureMvcMediator"; public function PureMvcMediator(initViewComponent:ViewComponent) { super(NAME, initViewComponent); } // cast view for convenient local use. public function get view():ViewComponent { return super.getViewComponent() as ViewComponent; } // listen for framework notices override public function listNotificationInterests():Array { return [ // DataNote.STUFF_DONE // ]; } // handle framework events override public function handleNotification(notice:INotification):void { switch (notice.getName()) { case DataNote.STUFF_DONE: // do stuff… break; } }} pureMVC mediator
  14. 14. package { public class PureMvcMediator extends Mediator implements IMediator { public static const NAME:String = "PureMvcMediator"; public function PureMvcMediator(initViewComponent:ViewComponent) { super(NAME, initViewComponent); } // cast view for convenient local use. public function get view():ViewComponent { return super.getViewComponent() as ViewComponent; } // listen for framework notices override public function listNotificationInterests():Array { return [ // DataNote.STUFF_DONE // ]; } // handle framework events override public function handleNotification(notice:INotification):void { switch (notice.getName()) { case DataNote.STUFF_DONE: // do stuff… break; } }} pureMVC mediator
  15. 15. package { public class MvcExpressMediator extends Mediator { [Inject] public var view:ViewComponent; override public function onRegister():void { // listen for framework events addHandler(DataMessage.STUFF_DONE, handleStuffDone); } // handle framework events private function handleStuffDone(params:DataChangeParamsVO):void { view.showStuff(params.dataParam1); } }} mvcExress mediator
  16. 16. package { public class MvcExpressMediator extends Mediator { [Inject] public var view:ViewComponent; override public function onRegister():void { // listen for framework events addHandler(DataMessage.STUFF_DONE, handleStuffDone); } // handle framework events private function handleStuffDone(params:DataChangeParamsVO):void { view.showStuff(params.dataParam1); } }} mvcExress mediator
  17. 17. package { public class MvcExpressMediator extends Mediator { [Inject] public var view:ViewComponent; override public function onRegister():void { // listen for framework events addHandler(DataMessage.STUFF_DONE, handleStuffDone); } // handle framework events private function handleStuffDone(params:DataChangeParamsVO):void { view.showStuff(params.dataParam1); } }} mvcExress mediator
  18. 18. package { public class MvcExpressMediator extends Mediator { [Inject] public var view:ViewComponent; override public function onRegister():void { // listen for framework events addHandler(DataMessage.STUFF_DONE, handleStuffDone); } // handle framework events private function handleStuffDone(params:DataChangeParamsVO):void { view.showStuff(params.dataParam1); } }} mvcExress mediator
  19. 19. Speed test data mvcExpress pureMVC robotlegs robotlegs 2 Command creation and execution: 0.00087 0.00219 0.00866 0.01894 Proxy inject into command: 0.00037 0.00024 0.00491 0.00247 Mediator create: 0.02100 0.02100 0.05100 0.13600 Mediator remove: 0.01700 0.10300 0.01850 0.05550 Communication 1 to 1: 0.00030 0.00060 0.00153 0.00141 Communication 1 to 10: 0.00073 0.00788 0.00670 0.00629 Communication 1 to 100: 0.00480 0.06897 0.05746 0.05071 1.0 /2.5 /10.0 /21.8 1.0 /0.7 /13.2 /6.6 1.0 /1.0 /2.4 /6.5 1.0 /6.1 /1.1 /3.3 1.0 /2.0 /5.0 /4.6 1.0 /10.9 /9.2 /8.7 1.0 /14.4 /12.0 /10.6 https://github.com/MindScriptAct/as3-mvcFramework-performanceTest https://github.com/MindScriptAct/as3-mvcFramework-performanceTest
  20. 20. Command runs /1ms pureMVC robotlegs robotlegs 2 mvcExpress mvcExpress (pooled) Command with nothing: 495.0 109.3 55.3 1010.1 1754.4 Command with 1 inject: 487.5 70.4 49.6 961.5 1694.9 Command with 2 injects: 458.7 58.6 47.2 724.6 1724.1 Command with 4 injects: 340.1 44.1 42.7 480.8 1783.3 Command performance
  21. 21. Command runs /1ms pureMVC robotlegs robotlegs 2 mvcExpress mvcExpress (pooled) Command with nothing: 495.0 109.3 55.3 1010.1 1754.4 Command with 1 inject: 487.5 70.4 49.6 961.5 1694.9 Command with 2 injects: 458.7 58.6 47.2 724.6 1724.1 Command with 4 injects: 340.1 44.1 42.7 480.8 1783.3 Command performance
  22. 22. Command runs /1ms pureMVC robotlegs robotlegs 2 mvcExpress mvcExpress (pooled) Command with nothing: 495.0 109.3 55.3 1010.1 1754.4 Command with 1 inject: 487.5 70.4 49.6 961.5 1694.9 Command with 2 injects: 458.7 58.6 47.2 724.6 1724.1 Command with 4 injects: 340.1 44.1 42.7 480.8 1783.3 Command performance
  23. 23. Command runs /1ms pureMVC robotlegs robotlegs 2 mvcExpress mvcExpress (pooled) Command with nothing: 495.0 109.3 55.3 1010.1 1754.4 Command with 1 inject: 487.5 70.4 49.6 961.5 1694.9 Command with 2 injects: 458.7 58.6 47.2 724.6 1724.1 Command with 4 injects: 340.1 44.1 42.7 480.8 1783.3 Command performance
  24. 24. Command runs /1ms pureMVC robotlegs robotlegs 2 mvcExpress mvcExpress (pooled) Command with nothing: 495.0 109.3 55.3 1010.1 1754.4 Command with 1 inject: 487.5 70.4 49.6 961.5 1694.9 Command with 2 injects: 458.7 58.6 47.2 724.6 1724.1 Command with 4 injects: 340.1 44.1 42.7 480.8 1783.3 Command performance
  25. 25. Command runs /1ms pureMVC robotlegs robotlegs 2 mvcExpress mvcExpress (pooled) Command with nothing: 495.0 109.3 55.3 1010.1 1754.4 Command with 1 inject: 487.5 70.4 49.6 961.5 1694.9 Command with 2 injects: 458.7 58.6 47.2 724.6 1724.1 Command with 4 injects: 340.1 44.1 42.7 480.8 1783.3 Command performance
  26. 26. Communication performance Direct communication: Indirect communication:
  27. 27. Communication performance Direct communication: Indirect communication:
  28. 28. Overview
  29. 29. Overview
  30. 30. Overview
  31. 31. Modular programming in  mvcExpress
  32. 32. Modular programming features ● Aggregation ● Communication ● Dependencies(data) ● Permission control (v1.4)
  33. 33. Aggregation mediatorMap.mediate(moduleB); var moduleB:ModuleB = new ModuleB(); view.addChild(moduleB);
  34. 34. Module communication
  35. 35. Module communication
  36. 36. Module communication sendScopeMessage("scopeName", "messageType", new ParamObject()); addScopeHandler("scopeName", "messageType", scopedMessageHandrlerFunction);
  37. 37. Module data sharing (data dependencies)
  38. 38. Module data sharing (data dependencies)
  39. 39. Module data sharing (data dependencies) proxyMap.scopeMap("scopeName", myProxyObject); [Inject(scope="scopeName")] public var myProxy:MyProxy;
  40. 40. Scope permissions registerScope(scopeName:String, messageSending:Boolean = true, messageReceiving:Boolean = true, proxieMapping:Boolean = false ):void
  41. 41. Dungeon viewer example
  42. 42. Modular programming pitfalls ● Planning is needed ● Good module should be able to stand as application on its own – Chat window – Stand alone tutorial ● Worst case scenario: extracting module/reintegrating module refactoring.
  43. 43. MvcExpress live
  44. 44. mvcExpress live ● mvcExpress live = mvcExpress + game engine – Continuous logic execution – Dynamic animations – Breaking execution in parts. (batching) ● Compatible with mvcExpress
  45. 45. mvcExress live diagram
  46. 46. mvcExress live diagram
  47. 47. mvcExress live diagram
  48. 48. mvcExress live diagram
  49. 49. mvcExress live diagram
  50. 50. mvcExress live diagram
  51. 51. mvcExress live diagram
  52. 52. Process examplepackage com.mindscriptact.testProject.engine { public class GameEngineProcess extends Process { override protected function onRegister():void { addTask(MoveHeroTask); addTask(MoveEnemiesTask); addTask(HeroCollideEnemiesTask); addTask(EnemySpawnTask); addTask(ShowHeroTask); addTask(ShowEnemiesTask); addHandler(Message.PAUSE_GAME, handleGamePause); } private function handleGamePause(isPaused:Boolean):void { if (isPaused) { disableTask(MoveHeroTask); disableTask(MoveEnemiesTask); } else { enableTask(MoveHeroTask); enableTask(MoveEnemiesTask); } } }}
  53. 53. Task example package com.mindscriptact.testProject.engine.tasks { public class ShowEnemiesTask extends Task { [Inject(constName="com.mindscriptact.testProject.constants.ProvideIds.ENEMY_DATAS")] public var enemyDatas:Vector.<EnemyVO>; [Inject(constName="com.mindscriptact.testProject.constants.ProvideIds.ENEMY_VIEWS")] public var enemyImages:Vector.<EnemySprite>; override public function run():void { for (var i:int = 0; i < enemyDatas.length; i++) { enemyImages[i].x = enemyDatas[i].x; enemyImages[i].y = enemyDatas[i].y; enemyImages[i].rotation = enemyDatas[i].rotations; } } }}
  54. 54. mvcExpress live testing package com.mindscriptact.testProject.engine.tasks { public class ShowEnemiesTask extends Task { [Inject(constName="com.mindscriptact.testProject.constants.ProvideIds.ENEMY_DATAS")] public var enemyDatas:Vector.<EnemyVO>; [Inject(constName="com.mindscriptact.testProject.constants.ProvideIds.ENEMY_VIEWS")] public var enemyImages:Vector.<EnemySprite>; override public function run():void { for (var i:int = 0; i < enemyDatas.length; i++) { enemyImages[i].x = enemyDatas[i].x; enemyImages[i].y = enemyDatas[i].y; enemyImages[i].rotation = enemyDatas[i].rotations; } } }} [Test] public function showEnemiesTask_enemyViewAndDataCount_isEqual():void { assert.equals(enemyDatas.length, enemyImages.length, "Enemies data and view count must be the same!"); } [Test(delay="500")] public function showEnemiesTask_enemyViewAndDataPosition_isEqual():void { for (var i:int = 0; i < enemyDatas.length; i++) { assert.equals(enemyImages[i].x, enemyDatas[i].x, "Enemy x is damaged. enemyId:" + enemyDatas[i].id); assert.equals(enemyImages[i].y, enemyDatas[i].y, "Enemy y is damaged. enemyId:" + enemyDatas[i].id); } }
  55. 55. Process run speed ● Best case: – Runs 1000000 empty Task's in 17 ms – 58823 empty tasks in 1 ms ● Worst case: – 13300 empty tasks in 1 ms
  56. 56. MvcExpress live overview ● Designed with games in mind but can be used in any application than has repeating logic to run. ● Processes and Task's are decoupled ● Convenient communication with MVC ● It is possible to break Model and View decoupling rules, but gives tools to detect it. ● It is fast! ● It just works!
  57. 57. On learning  curve
  58. 58. On learning curve ● MVC framework initial learning curve is steep... ● But if you learned one – learning another is easy! http://mvcexpress.org/documentation/ https://github.com/MindScriptAct/mvcExpress-examples Also I do workshops. http://mvcexpress.org/documentation/ https://github.com/MindScriptAct/mvcExpress-examples Also I do workshops.
  59. 59. MvcExpress logger
  60. 60. Links http://mvcexpress.org/ https://github.com/MindScriptAct/mvcExpress-framework https://github.com/MindScriptAct/mvcExpress-examples https://github.com/MindScriptAct/mvcExpress-downloads http://puremvc.org/ http://www.robotlegs.org/ Twitter : @Deril Thank you for your time! http://mvcexpress.org/ https://github.com/MindScriptAct/mvcExpress-framework https://github.com/MindScriptAct/mvcExpress-examples https://github.com/MindScriptAct/mvcExpress-downloads http://puremvc.org/ http://www.robotlegs.org/ Twitter : @Deril
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×