{"action":"created","issue":{"url":"https://api.github.com/repos/massiveinteractive/mmvc/issues/17","labels_url":"https://api.github.com/repos/massiveinteractive/mmvc/issues/17/labels{/name}","comments_url":"https://api.github.com/repos/massiveinteractive/mmvc/issues/17/comments","events_url":"https://api.github.com/repos/massiveinteractive/mmvc/issues/17/events","html_url":"https://github.com/massiveinteractive/mmvc/issues/17","id":44575110,"number":17,"title":"commands triggered by anything not just signals","user":{"login":"jozefchutka","id":750041,"avatar_url":"https://avatars.githubusercontent.com/u/750041?v=3","gravatar_id":"","url":"https://api.github.com/users/jozefchutka","html_url":"https://github.com/jozefchutka","followers_url":"https://api.github.com/users/jozefchutka/followers","following_url":"https://api.github.com/users/jozefchutka/following{/other_user}","gists_url":"https://api.github.com/users/jozefchutka/gists{/gist_id}","starred_url":"https://api.github.com/users/jozefchutka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jozefchutka/subscriptions","organizations_url":"https://api.github.com/users/jozefchutka/orgs","repos_url":"https://api.github.com/users/jozefchutka/repos","events_url":"https://api.github.com/users/jozefchutka/events{/privacy}","received_events_url":"https://api.github.com/users/jozefchutka/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":12,"created_at":"2014-10-01T15:13:24Z","updated_at":"2015-01-05T16:17:55Z","closed_at":null,"body":"We hit some major issues when using signals for triggering commands. Because signals are singletons and so its hard to maintain response in case the signal.dispatch is executed in loop, not to mention unnecessary memory footprint of having a custom signal for each command...\r\n\r\nThe solution is rather very simple. It uses TriggerMap to map any trigger (class) to any command. Each command can be dispatched with a specific instance of trigger so its much easier to handle related \"response\", and much more easier to obtain trigger instance/value in command:\r\n```haxe\r\npackage mmvc.impl;\r\n\r\nimport haxe.ds.StringMap;\r\n\r\nimport mmvc.api.ICommand;\r\nimport mmvc.impl.Actor;\r\n\r\nclass TriggerMap extends Actor\r\n{\r\n\tvar map:StringMap<Class<ICommand>>;\r\n\r\n\tpublic function new()\r\n\t{\r\n\t\tmap = new StringMap<Class<ICommand>>();\r\n\r\n\t\tsuper();\r\n\t}\r\n\r\n\tpublic function dispatch(trigger:Dynamic)\r\n\t{\r\n\t\tvar triggerClass = Type.getClass(trigger);\r\n\t\tvar triggerClassName = Type.getClassName(triggerClass);\r\n\t\tif(!map.exists(triggerClassName))\r\n\t\t\tthrow \"Command for trigger \" + triggerClassName + \" is not defined.\";\r\n\r\n\t\tinjector.mapValue(triggerClass, trigger, \"trigger\");\r\n\t\tvar command = injector.instantiate(map.get(triggerClassName));\r\n\t\tinjector.unmap(triggerClass, \"trigger\");\r\n\r\n\t\tcommand.execute();\r\n\t}\r\n\r\n\tpublic function mapCommand(trigger:Class<Dynamic>, command:Class<ICommand>)\r\n\t{\r\n\t\tvar triggerClassName = Type.getClassName(trigger);\r\n\t\tif(map.exists(triggerClassName))\r\n\t\t\tthrow \"Command for trigger \" + triggerClassName + \" is already defined.\";\r\n\r\n\t\tmap.set(triggerClassName, command);\r\n\t}\r\n\r\n\tpublic function unmapCommand(trigger:Class<Dynamic>)\r\n\t{\r\n\t\tvar triggerClassName = Type.getClassName(trigger);\r\n\t\tmap.remove(triggerClassName);\r\n\t}\r\n}\r\n```\r\n\r\nThe Command implementation in this case needs to be tweaked and Signal injection removed:\r\n```haxe\r\npackage mmvc.impl;\r\n\r\nimport minject.Injector;\r\n\r\nimport mmvc.api.ICommand;\r\nimport mmvc.api.ICommandMap;\r\nimport mmvc.api.IMediatorMap;\r\nimport mmvc.api.IViewContainer;\r\n\r\nclass Command implements ICommand\r\n{\r\n\t@inject public var contextView:IViewContainer;\r\n\t@inject public var commandMap:ICommandMap;\r\n\t@inject public var injector:Injector;\r\n\t@inject public var mediatorMap:IMediatorMap;\r\n\r\n\tpublic function new():Void{}\r\n\tpublic function execute(){}\r\n}\r\n```\r\n\r\nand finally the usage. Lets map some commands in context:\r\n```haxe\r\ninjector.mapSingleton(TriggerMap);\r\nvar triggerMap:TriggerMap = injector.getInstance(TriggerMap);\r\n\r\ntriggerMap.mapCommand(String, StringCommand);\r\ntriggerMap.mapCommand(Int, IntCommand);\r\ntriggerMap.mapCommand(MyVO, VOCommand);\r\n```\r\n\r\ntriggering in mediator:\r\n```haxe\r\nclass MyMediator extends Mediator\r\n{\r\n\t@inject public var triggerMap:TriggerMap;\r\n\toverride function onRegister()\r\n\t{\r\n\t\ttriggerMap.dispatch(\"hello world\");\r\n\t}\r\n}\r\n```\r\n\r\n```haxe\r\nclass StringCommand extends Command\r\n{\r\n\t@inject(\"trigger\") public var trigger:String;\r\n\r\n\toverride function execute()\r\n\t{\r\n\t\ttrace(\"StringCommand executed = \" + trigger);\r\n\t}\r\n}\r\n\r\nclass IntCommand extends Command\r\n{\r\n\t@inject(\"trigger\") public var trigger:Int;\r\n\r\n\toverride function execute()\r\n\t{\r\n\t\ttrace(\"StringCommand executed = \" + trigger);\r\n\t}\r\n}\r\n\r\nclass VOCommand extends Command\r\n{\r\n\t@inject(\"trigger\") public var trigger:MyVO;\r\n\r\n\toverride function execute()\r\n\t{\r\n\t\ttrace(\"StringCommand executed = \" + Std.string(trigger));\r\n\t}\r\n}\r\n```\r\n\r\nthis approach lets you implement triggerMap on project level but if we decide to implement it on mmvc level that would be even more awesome"},"comment":{"url":"https://api.github.com/repos/massiveinteractive/mmvc/issues/comments/68731122","html_url":"https://github.com/massiveinteractive/mmvc/issues/17#issuecomment-68731122","issue_url":"https://api.github.com/repos/massiveinteractive/mmvc/issues/17","id":68731122,"user":{"login":"jozefchutka","id":750041,"avatar_url":"https://avatars.githubusercontent.com/u/750041?v=3","gravatar_id":"","url":"https://api.github.com/users/jozefchutka","html_url":"https://github.com/jozefchutka","followers_url":"https://api.github.com/users/jozefchutka/followers","following_url":"https://api.github.com/users/jozefchutka/following{/other_user}","gists_url":"https://api.github.com/users/jozefchutka/gists{/gist_id}","starred_url":"https://api.github.com/users/jozefchutka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jozefchutka/subscriptions","organizations_url":"https://api.github.com/users/jozefchutka/orgs","repos_url":"https://api.github.com/users/jozefchutka/repos","events_url":"https://api.github.com/users/jozefchutka/events{/privacy}","received_events_url":"https://api.github.com/users/jozefchutka/received_events","type":"User","site_admin":false},"created_at":"2015-01-05T16:17:55Z","updated_at":"2015-01-05T16:17:55Z","body":"PR here https://github.com/massiveinteractive/mmvc/pull/20"}}