The Next Step in AS3 Framework Evolution - FITC Amsterdam 2013
Upcoming SlideShare
Loading in...5
×
 

The Next Step in AS3 Framework Evolution - FITC Amsterdam 2013

on

  • 9,591 views

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

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.

Statistics

Views

Total Views
9,591
Views on SlideShare
7,546
Embed Views
2,045

Actions

Likes
6
Downloads
16
Comments
5

5 Embeds 2,045

http://mvcexpress.org 1110
http://www.scoop.it 926
http://translate.googleusercontent.com 6
http://webcache.googleusercontent.com 2
https://www.google.com 1

Accessibility

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • @skolesnyk Hi, I checked Hummingbird, it looks interesting, it has different vision how MVC framework should look like.

    Personally I don't like that controller and view is not decoupled, customized view objects,(mvcExpress does not have dependencies to any Flash api view class, you can use it with anything... starling, 3d, plain Sprites - you name it.) and it has too many static stuff for my taste.
    But it has most important view-module decoupling implemented, and direct access to controller improves performance.

    So I guess it is question of taste... :) witch vision you like the most.
    Are you sure you want to
    Your message goes here
    Processing…
  • There is a discussion re different MVCs used with Starling. Check http://forum.starling-framework.org/topic/hummingbird-mvc-framework#post-32949
    Are you sure you want to
    Your message goes here
    Processing…
  • Hi, I have written several experimental projects with mvcExpress live and starling - works very good. 2 game jam projects can be found on github.I will check what kind and why robotlegs need a plugin. Thanks!
    Are you sure you want to
    Your message goes here
    Processing…
  • Thanks for sharing. Do you think it would work with Starling out of the box or there should be a plugin made similar to https://github.com/s9tpepper/robotlegs-starling-plugin ?
    Are you sure you want to
    Your message goes here
    Processing…
  • Nice and neat.
    Well done sr.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

The Next Step in AS3 Framework Evolution - FITC Amsterdam 2013 The Next Step in AS3 Framework Evolution - FITC Amsterdam 2013 Presentation Transcript

  • 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 : @Deril
  • 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(2008) [flex only] ● Robotlegs(2009) ● Swiz(2009) [flex only] ● MvcExpress(2012) ● Robotlegs 2 (2012) (in beta) (ActionScript 3.0 released in 2006)
  • 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)
  • 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
  • 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?
  • 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...
  • 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!
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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", "messageType", scopedMessageHandrlerFunction);
  • Module data sharing (data dependencies)
  • Module data sharing (data dependencies)
  • Module data sharing (data dependencies) proxyMap.scopeMap("scopeName", myProxyObject); [Inject(scope="scopeName")] public var myProxy:MyProxy;
  • Scope permissions registerScope(scopeName:String, messageSending:Boolean = true, messageReceiving:Boolean = true, proxieMapping:Boolean = false ):void
  • Dungeon viewer example
  • 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.
  • MvcExpress live
  • mvcExpress live ● mvcExpress live = mvcExpress + game engine – Continuous logic execution – Dynamic animations – Breaking execution in parts. (batching) ● Compatible with mvcExpress
  • 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 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); } } }}
  • 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; } } }}
  • 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); } }
  • 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
  • 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!
  • On learning  curve
  • 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.
  • MvcExpress logger
  • 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