robotlegs / robotlegs-framework Goto Github PK
View Code? Open in Web Editor NEWAn ActionScript 3 application framework for Flash and Flex
Home Page: https://robotlegs.tenderapp.com/
License: MIT License
An ActionScript 3 application framework for Flash and Flex
Home Page: https://robotlegs.tenderapp.com/
License: MIT License
Need to run through and make sure that there are readme's for all packages, extensions etc.
There is a circular reference bug if you have singletons that inject eachother.
Trivial example (Flex Builder 3 AS3 project) here: http://www.stevensacks.net/xfer/circbug.zip
And the output:
undefined
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
Hi , I think that would be useful to add the inverse function of addViewListener and addContextListener
Create a pom.xml file so Robotlegs can be built, tested and deployed using Maven, as an alternative to Ant.
To discuss the Robotlegs version 2 website please use this issue tracker:
As described in this knowledge base entry, the delayed removal of mediators to work around the undetectability of re-parenting can cause problems with wrongly-received events in the mediator.
We should investigate some way of signalling the impending removal so that the mediator (or other type of view handler object) can work around that issue.
An issue to discuss RL2's mediatorMap and mediators
An issue to discuss the Guards and Hooks API and implementation.
What extensions would you like to see bundled with Robotlegs 2 (or officially provided and supported)?
An issue to discuss the Context API and implementation.
There are two options for mediator view matching:
Allows a great deal of flexibility, but there are concerns that if offers too much in the way of "rope".
Restricts usage by employing a custom matcher interface tailored for "type matching". This reduces the "rope" factor, but is less flexible.
Personally I'm keen for Option 1 - even if purely to keep the RL2 API consistent.
Which option are you in favour of?
Hey not sure if this matters to you but I would like to get a html report regardless of test failures. I want to halt on errors, but not test failures. This allows me to see a report and view the failures in a "prettier" fashion.
To do this I just set the flexunit property "haltOnFailures" to false. This is not an "issue" but seems to be a good choice.
Best,
Ken
Mapping:
messageCommandMap
.map( LoginMessage )
.toCommand( LoginCommand );
v1. works fine for:
messageDispatcher.dispatchMessage( LoginMessage );
v2. but does not work for:
messageDispatcher.dispatchMessage( new LoginMessage( userName, userPass ) );
How to map LoginMessage to work with sample v2?
Hi,
i have a class =>
http://github.com/FrancisVarga/basilicom-core/blob/master/src/de/basilicom/contentBuilder/vo/ElementItem.as
I inject there a class =>
http://github.com/FrancisVarga/basilicom-core/blob/master/src/de/basilicom/core/models/RessourceManager.as
But that model will not Inject by debugging is that NULL...
Any ideas why?!
Example =>
http://github.com/FrancisVarga/basicore-testCenter
In RL2, mediators are created for views that land on the stage and match a mapped matcher.
The matchers are special cases of Hamcrest matchers.
The reason for imposing a special case and not just any old Hamcrest matcher is that matching against dynamic, mutable properties is potentially unsafe and can create weird runtime behaviours - so we've decided (after discussion, here: #62 ) to match mediators only against immutable properties.
In addition to TypeMatcher and PackageMatcher, I'm considering a CompositionMatcher.
The CompositionMatcher would be matching something immutable - whether or not the object that just landed on the stage implements a type that includes a specific kind of member.
But I can already do that with an interface...
The CompositionMatcher would in reality only be a different way of specifying the same behaviour that you could get by ensuring that any class that 'has a Gun' implements an interface with a getter or setter for 'Gun'.
So why bother?
Some people find the creation of multiple small interfaces for this kind of purpose to be a bit icky. The interface also requires that you use getter / setters on your Gun - and you might want to make it a public property.
That's the question I need your input on. What I'm currently riffing on is:
new CompositionMatcher().hasA(Gun);
new CompositionMatcher().hasANamed(Gun, 'gun');
new CompositionMatcher()
.allOf( new PropertyMatcher( Gun, 'gun' ),
new PropertyMatcher( Dog ) );
new CompositionMatcher()
.anyOf( new PropertyMatcher( Gun, 'gun' ),
new PropertyMatcher( Bomb, 'bomb' ) );
new CompositionMatcher()
.anyOf( new PropertyMatcher( Gun, 'gun' ),
new PropertyMatcher( Bomb, 'bomb' ) )
.noneOf( new PropertyMatcher( Handcuffs, 'handcuffs' ) );
new CompositionMatcher().matchesType(typeMatcher).hasA(Gun);
new CompositionMatcher().matchesPackage(packageMatcher).hasA(Dog);
The provision of a name as well as a type is optional.
Note: the existence of the member is what is matched, the member itself can have a value of null and still pass the matcher.
Is this useful? After all - Robotlegs already allows you to easily mediate the children of a view, so perhaps this is not required at all?
The example is a little misleading because it nods towards properties that are more likely to be found in games, and those are best dealt with in an entity based (or other) Robotlegs extension.
Do people have use cases that this matcher would apply to? And if so, does the API I've described fit well with what you would need from it?
Type / Package matching would be necessary as well if you wanted to inject your view into your mediator as anything other than a DisplayObject. In which case perhaps there is no way to avoid the creation of shallow interfaces (otherwise you'd be casting inside the mediator to be able to access these properties).
Thanks in advance for any input...
An issue to discuss the View Map API and implementation.
public class MyAppConfig {
[Inject]
public var mediatorMap:IMediatorMap;
[PostConstruct]
public function configure():void {
mediatorMap.mapView( MyApp ).toMediator( MyAppMediator );
}
}
context = new Context(
ClassicRobotlegsBundle
MyAppConfig,
this
);
MyAppMediator will be never created and does not matter when view was added to stage before config initialize or right after or 10 seconds later.
It is do not works for main context and for any child context.
For now the solution is:
public class MyAppConfig {
[Inject]
public var mediatorMap:IMediatorMap;
private var contextView:DisplayObjectContainer;
public function MyAppConfig(contextView:DisplayObjectContainer):void {
this.contextView = contextView;
}
[PostConstruct]
public function configure():void {
mediatorMap.mapView( MyApp ).toMediator( MyAppMediator );
mediatorMap
.getViewMapping(MyApp)
.forMediator(MyAppMediator)
.createMediator(contextView);
}
}
context = new Context(
ClassicRobotlegsBundle
new MyAppConfig(this),
this
);
Thanks to Shaun Smith for help!
Why is injection in actor's not allowed?! i think it makes complex json/xml parsing easier...
An issue to discuss to discuss the Context Builder API and implementation.
I am struggling to get a very basic start to robot legs !
here is my main class that tries to create a context class that has issues
package
{
import flash.display.Sprite;
import com.theapp.TestContext;
public class Main extends Sprite
{
public function Main()
{
context = new TestContext();
context.contextView = this;
}
}
}
TestContext.as
package com.theapp
{
import flash.display.DisplayObjectContainer;
import org.robotlegs.core.IContext;
import org.robotlegs.mvcs.Context;
public class TestContext extends Context implements IContext
{
public function TestContext(contextView:DisplayObjectContainer)
{
super(contextView);
}
override public function startup() : void
{
super.startup();
}
}
}
error :
Exception fault: TypeError: Error #2023: Class TestContext$ must inherit from Sprite to link to the root.
Thanks for any guidance on this...
An issue to discuss the Mediator Map API and implementation.
I think we should develop a "plugin" for localization in robotlegs like this (parsley)
Any idea?
I wonder if the SignalCommandMap should be enhanced for v2 to include support for named parameters. Regardless, it will need to be re-built as a v2 extension. Here is how the EventCommandMap (currently) integrates with the CommandMap:
Creating a CommandMap based extension requires writing 4 files:
A trigger specific API
An implementation of that API
An implementation of the ICommandTrigger API
An extension file for installing the extension
Issue to discuss the Robotlegs 2 EventMap API and implementation.
See issue 8. same architekture...
I have in my context =>
http://github.com/FrancisVarga/basicore-testCenter/blob/master/src/de/basilicom/mvcs/ApplicationContext.as
register my MainContainerMediator in my contenxt my BulkloaderHandlerCommand get the BulkloaderEvent's but not my MainContainerMediator... It's very weird!
http://github.com/FrancisVarga/basicore-testCenter/blob/master/src/de/basilicom/mvcs/commands/BulkloaderHandlerCommand.as
I was playing around with this HelloWorld example and I ran into a problem using Context inside the Declerations tag:
<fx:Declarations>
<context:AppContext contextView="{this}" />
</fx:Declarations>
The probelm was that the contextView
was getting set twice, which seems to cause Robotlegs 1.5.0 to freak out.
I'm using Flex 4.5.1 and Flash Builder 4.5.
I created some tests and it seems that any class declared in the Declarations tag will get properties with binding expressions set twice. Always, even if the binding is to a property of a basic type, like Number, who's value does not change at any point.
Weirdly, if the class is declared in the root-tag/DispalyList (in my case I created a test that extended UIComponent, so it could exist outside the Declarations tag) this double setting of the properties with binding expressions does not seem to occur.
I don't know if this is some weird configuration thing with my Flex setup, or if this is a 4.5 only issue… but I thought I'd bring it up as it was very frustrating because I liked the style of declaring the context as a tag, instead of using raw Actionscript.
My workaround is to patch it when extending Context — my AppContext.as has this:
override public function set contextView(value:DisplayObjectContainer):void
{
if ( ! contextView ) super.contextView = value;
}
Basically it just ensures that if contextView has already been set, it doesn't get set again.
Let me know if I'm missing something.
This condition should never verify if (callbacksByCommandClass == null) return;
in this context :
var callbacksByCommandClass:Dictionary = eventClassMap[eventClass || Event];
if (callbacksByCommandClass == null) return;
As you might have seen already there is a job for RL2 on my Jenkins server which compiles and tests RL2 after every push to the 'version2' branch. http://jenkinsci.devboy.org/job/robotlegs-framework/
The jobs runs the buildr script I created together with @darscan, so to get proper metrics the buildfile needs to be up-to-date. But no reason to worry :)
By the way, metrics: Do you have anything in mind you want me to add? Like flexcover or flexPMD?
We can now add a variety of automated testing, building and releasing of RL2. For example I could deploy every build right now as a snapshot release to my maven repository at nexus.devboy.org. (Heres a maven discussion with @justinjmoses #42 )
Just let me know what you are interested in doing, and I'll try to make it happen.
Hi,
The MediatorMap needs a "hasMapping" function that returns a Boolean whether a certain mapping has been made or not.
e.g.
var hasViewBeenMapped : Boolean = mediatorMap.hasMapping(SomeView, SomeViewMediator);
refer to org / robotlegs / v2 / core / impl / itemPassesFilter.as
it should be ItemPassesFilter.as isn't it? (big "i")
An issue to discuss the new Extension architecture.
Discussion started here: http://groups.google.com/group/robotlegs/msg/c7e9497ae03158a0
There're 2 occurrences of mediatorMap in the XML_CONFIG const definition. It's causing issues in Flash IDE published swf: commandMap is null in Command instances.
For performance reasons the current API and implementation for view management is tied to Display Objects.
What do we need to do to enable non Display Object integration to support libraries like Starling, Flex mobile and the various 3D frameworks?
Robotlegs v1 enabled framework extension by exposing protected methods that could be overridden. I believe this was a fundamental design flaw.
Firstly, those protected members then became part of the API and we couldn't change them in minor or patch releases without breaking our semantic versioning.
Secondly, encouraging extension in itself was a mistake as it lead to inheritance lock-in nightmares. Think: SignalEnabledCovariantMediationMacroCommandContext.
As Robotlegs v2 focuses on Composition Over Inheritance, I propose switching to private members wherever possible.
"But what if I want to make a specialised MediatorMap/CommandMap etc?"
If extension by inheritance seems like the only answer, then we've designed those extensions incorrectly. They should be flexible enough to have new features installed without requiring extension.
For example, with the CommandMap we now have CommandTriggers that decouple the CommandMap itself from the specific requirements of Events/Signals. One does not need to extend CommandMap to add Signal support.
Guards and Hooks should also allow for greater flexibility without requiring extension.
Another way to look at it is like this:
RL1 provided interfaces for the core framework apparatus and default implementations. Users coded against those interfaces expecting things to work in the documented fashion. If somebody came along and provided a modified (or completely different) implementation that conformed to the same interface, then the behaviour of that apparatus would be different without being explicit.
For framework apparatus we want provable, reliable behaviour. By providing an Interface and a default implementation with protected members we're effectively saying: "Here, this API is perfect, but the implementation might not be, so feel free to extend/modify/replace the implementation". But if the implementation provided by the framework is wrong, surely we should fix it at the source directly?
I was trying to do a build and got this far:
compile:
[echo] [compile] Compiling release SWC
[echo] [compile] Using Flex SDK at: /Applications/Adobe Flash Builder 4 Plug-in/sdks/4.1.0
[java] Loading configuration file /Applications/Adobe Flash Builder 4 Plug-in/sdks/4.1.0/frameworks/flex-config.xml
[java] /Users/krogers/Git/robotlegs-framework/src/robotlegs/bender/framework/object/identity/UID.as(28): col: 14 Error: Call to a possibly undefined method getQualifiedClassName.
[java]
[java] source = getQualifiedClassName(source).split("::").pop();
[java] ^
[java]
[java] /Users/krogers/Git/robotlegs-framework/src/robotlegs/bender/framework/object/identity/UID.as(10): col: 16 Error: Definition avmplus:getQualifiedClassName could not be found.
[java]
[java] import avmplus.getQualifiedClassName;
[java] ^
[java]
BUILD FAILED
/Users/krogers/Git/robotlegs-framework/build.xml:54: Java returned: 2
Hi, I just updated my current project from RL 1.4 to 1.5.1 and everything seems fine, except that I get this warning everytime that I dispatch a new Signal. The Signal carries a Sprite and a String reference.
Warning: Injector already has a rule for type "flash.display::Sprite", named "".
If you have overwritten this mapping intentionally you can use "injector.unmap()" prior to your replacement mapping in order to avoid seeing this message.
Warning: Injector already has a rule for type "String", named "".
If you have overwritten this mapping intentionally you can use "injector.unmap()" prior to your replacement mapping in order to avoid seeing this message.
Am I doing something wrong? I don't understand what the warning means.
In my config class:
[PostConstruct]
public function init():void
{
mediatorMap.mapView(iAppView).toMediator(AppViewMediator);
commandMap.map(TestSignal).toCommand(TestCommand);
}
This throws an error:
Error: Injector is missing a mapping to handle injection into property "view" of object "[object AppViewMediator]" with type "[class AppViewMediator]". Target dependency: "views.api::iAppView|"
at org.swiftsuspenders.typedescriptions::PropertyInjectionPoint/applyInjection()[/Users/till/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/typedescriptions/PropertyInjectionPoint.as:48]
at org.swiftsuspenders::Injector/applyInjectionPoints()[/Users/till/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/Injector.as:468]
at org.swiftsuspenders::Injector/org.swiftsuspenders.internal::instantiateUnmapped()[/Users/till/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/Injector.as:403]
at org.swiftsuspenders::Injector/getInstance()[/Users/till/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/Injector.as:331]
at robotlegs.bender.extensions.mediatorMap.impl::MediatorFactory/createMediator()[/Users/krogers/Git/robotlegs-framework/src/robotlegs/bender/extensions/mediatorMap/impl/MediatorFactory.as:60]
at robotlegs.bender.extensions.mediatorMap.impl::MediatorMapping/createMediator()[/Users/krogers/Git/robotlegs-framework/src/robotlegs/bender/extensions/mediatorMap/impl/MediatorMapping.as:98]
at robotlegs.bender.extensions.mediatorMap.impl::MediatorViewHandler/handleView()[/Users/krogers/Git/robotlegs-framework/src/robotlegs/bender/extensions/mediatorMap/impl/MediatorViewHandler.as:77]
at robotlegs.bender.extensions.mediatorMap.impl::MediatorMap/handleView()[/Users/krogers/Git/robotlegs-framework/src/robotlegs/bender/extensions/mediatorMap/impl/MediatorMap.as:79]
at robotlegs.bender.extensions.viewManager.impl::ContainerBinding/handleView()[/Users/krogers/Git/robotlegs-framework/src/robotlegs/bender/extensions/viewManager/impl/ContainerBinding.as:93]
at robotlegs.bender.extensions.viewManager.impl::StageObserver/onViewAddedToStage()[/Users/krogers/Git/robotlegs-framework/src/robotlegs/bender/extensions/viewManager/impl/StageObserver.as:94]
I am trying to update my simple example app for an extension I am working on. This was working before using this line:
mediatorMap.map(iAppView).toMediator(AppViewMediator);
instead iof
mediatorMap.mapView(iAppView).toMediator(AppViewMediator);
But it seems I can no longer use "map". Not sure if that helps!
I think most people dig the logo. I was wondering if it could do with a tiny update though?
An issue to discuss the API and implementation of modularity in Robotlegs 2.
Line #62 of Mediatorbase.as has a bug that has shown up in our application. This line needs to check to see if on remove has been called before adding the creation complete listener.
There are cases in our app where the state switches fast enough ( loading state to app view state ) that the onRemove is called before the onRegister gets called. This makes it so that the creation complete listeners are added to the viewComponent after they should have been removed. This adds a pointer to a view that should be gone.
Hi i have a problem with injection
Example =>
public class MyCore extends Context{
override public function startup():void{
injector.mapSingleton(ElementModel);
}
}
public class CurrentCoreProject extends MyCore{
override public function startup():void{
super.startup();
}
}
public class MyClass{
[Inject] public var model : ElementModel; // null can't inject this class
}
I hope i dave good describe my issue :D
i just run unit test via SwiftSuspenders-v1.6.0.swc and get plenty of this
Warning: Injector already has a rule for type "org.robotlegs.core::IReflector", named "".
If you have overwritten this mapping intentionally you can use "injector.unmap()" prior to your replacement mapping in order to avoid seeing this message.
Warning: Injector already has a rule for type "org.robotlegs.core::IInjector", named "".
If you have overwritten this mapping intentionally you can use "injector.unmap()" prior to your replacement mapping in order to avoid seeing this message.
Warning: Injector already has a rule for type "flash.events::IEventDispatcher", named "".
If you have overwritten this mapping intentionally you can use "injector.unmap()" prior to your replacement mapping in order to avoid seeing this message.
this annoying for me because i'm don't know that this is a right warning or wrong
then the question is are we gonna fix it or maybe i need to try find the way to turn it off instead?
thanks
An extension which provides print functionality.
Print features are part of many websites. CSS media types present web pages in a format which is print ready.
I developed a code base for printing text based content to PDF some time ago and I'd like to port it to Robotlegs V2.
Is anyone already developing something for this?
Would anyone like to contribute to getting this functionality built?
Can anyone provide any guidance on the structure for the API?
I'm a noob at building in general, so please excuse if I'm missing something.
as stated, the ant build attempts to delete a folder in the project root called "dist" how ever this folder does not exist.
if i create the folder, the error does not occur.
cheers
Should the framework log its internal actions? And, should we use as3commons Logging?
The conversation started here: http://knowledge.robotlegs.org/discussions/feedback/25-robotlegs-v2-logging
Speaking of cruft, is the org really needed? I've taken to dropping the TLD in my general work where I have the choice.
An issue to discuss the Command Map API and implementation.
Need to run through and make sure that all APIs have asdocs.
In Robotlegs 1, the MediatorMap employed a strategy of 'waiting for 1 frame' to check that a view really had been removed from the display list, before cleaning up its mediators.
In addition, when a view was passed to the mediatorMap to be mediated, we first checked that it wasn't one with a mediator marked for removal by the system. In this way, if a view was added and removed within a frame - usually by being reparented - its mediator would persist.
The reason for this was primarily that Flex 3 Scrollable Containers can do reparenting behind your back (they secretly remove and add items when you cross the threshold for needing the scrolling to be activated).
The Flash TileList component also does this sneaky reparenting during scrolling. Items still in view can be reparented when any other item is introduced to the view area.
There was a small but important bug in the RL1 process - it was possible to get false positives on the eventMap when your mediator was loitering for a frame. We now have a robust workaround for this bug: suspending / resuming eventMap activity within the mediator itself when the view is removed / added.
Let's assume for a moment that it's possible to employ a much more specific bug-fix for the known scrollable container problems, and that we can provide fixes for any similar problems emerging future. Or that we exclude those components from the game completely - perhaps by specifying Flex 4, and saying that contents of TileLists can't be mediated.
A use case: a column-based UI in which the user can drag parts of the UI from one column to another.
It's common to have to attach a component to a higher 'layer' during dragging and then snap it back to the lower layer in which it normally lives when the drag is complete. If the initialize function in your Mediator also populates it in some way, you might not want that process to be repeated.
In Robotlegs 2, rather than having one enormous context view, you can target specific DisplayObjectContainers to be monitored for added / removed events. If you reparented the view in question into a DOC which has a different set of MediatorMap rules applied, or is outside of the scope of the current MediatorMap, your mediator should probably be cleaned up.
In the case of moving to a new 'context view', that context may have a different eventDispatcher to the one referenced in the eventMap inside your mediator and so on.
I'm a 'mediators-don't-hold-state' person myself, but let's assume for a moment that you've got a reason to hold a reference to the view's parent in the mediator. When the view is reparented, that parent might change.
Should your mediator persist or vanish if your view would no longer pass your guards, and all you've done is drag it around? Possibly you've even dragged the item and returned it to the place where it was originally.
Of course this would probably be a sign that you've written your guards in a strange way, but - leaving guards aside - should any hooks be reapplied? You could write all your hooks with their own internal guard clauses (and in many cases this will be necessary - you'll need to cache which views you've already skinned so that you don't keep reskinning them over and over). But all of this is potentially inefficient.
Here's a proposal - to which we'd like your responses. It really is only a draft attempt to figure out the least annoying strategy to employ. Inevitably any strategy will sometimes be incorrect - so the aim is to make it right more often that it's wrong, and ensure it can be overridden in those cases.
The most important thing is that the strategy is easy to understand - developers need to know what to expect from the framework.
destroyOnReparent = true;
.A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.