Browse files

Updated MediatorMap readme, added matching readme, fixed require/exte…

…nd in other readme files.
  • Loading branch information...
1 parent 162a19b commit 837f10c67b6284f14948c74f5df6a05daf6a9d56 @Stray Stray committed May 3, 2012
View
2 src/robotlegs/bender/extensions/commandMap/readme.md
@@ -12,4 +12,4 @@ It is not intended to be used directly.
### At Runtime
- _context.require(CommandMapExtension);
+ _context.extend(CommandMapExtension);
View
2 src/robotlegs/bender/extensions/eventCommandMap/readme.md
@@ -36,7 +36,7 @@ This extension requires the following extensions:
Assuming that the EventDispatcher and CommandMap extensions have already been installed:
- _context.require(EventCommandMapExtension);
+ _context.extend(EventCommandMapExtension);
## Extension Usage
View
55 src/robotlegs/bender/extensions/matching/readme.md
@@ -0,0 +1,55 @@
+# Matching Extension
+
+## Overview
+
+TypeMatchers allow you to build up rich descriptions of objects based on their type - the class, superclass chain and interfaces the implement.
+
+## Extension Installation
+
+This extension does not need to be installed, it is used by the MediatorMap extension, but can also be used in other extensions.
+
+## TypeMatcher Usage
+
+You create a typeMatcher using new:
+
+ new TypeMatcher()
+
+Any number of calls to the following api can be chained:
+
+ allOf(...types)
+ anyOf(...types)
+ noneOf(...types)
+
+The parameter `...types` can be an array of types or simply a list. Using an array will allow you to use sets of types to configure multiple matchers.
+
+TypeMatchers are locked as soon as they have been used for matching, but you can explicitly lock your TypeMatcher with a call to
+
+ lock()
+
+Once locked, the only api available is
+
+ clone()
+
+This creates a duplicate TypeMatcher, which is unlocked, so that you can further customise this matcher.
+
+TypeMatchers are not internally checked for conflicts, so it's your responsibility to ensure that your rules make sense.
+
+There is no 'or' provided. Instead, use multiple matchers and map each of them to the same rules - ensuring that your rules aren't nested, or multiple matches will occur. For guidance on testing your matchers check out the TypeMatcher unit tests.
+
+## PackageMatcher Usage
+
+The package matcher has the following api:
+
+ require(fullPackage:String)
+ anyOf(...packages)
+ allOf(...pacakges)
+
+You can only `require` one package. Multiple calls to `anyOf` and `allOf` can be chained. Multiple calls to `require` will throw an error.
+
+The package matcher will be locked the first time it is used, but can be explicitly locked with a call to
+
+ lock();
+
+## Building your own Matchers
+
+... info to follow
View
113 src/robotlegs/bender/extensions/mediatorMap/readme.md
@@ -6,7 +6,116 @@ The mediator map provides automagic mediator creation for mapped views landing o
## Extension Installation
+ context.extend(MediatorMapExtension);
-## Extension Usage
+## MediatorMap Usage
-... coming soon
+The Robotlegs 2 mediatorMap is designed to support _co-variant_ mediation. This means that multiple mediators can be mediating on behalf of one object, and that the combination of mediators created is driven by the object's type (class, superclasses and interfaces).
+
+### Making mappings
+
+You map either a specific type or a TypeMatcher to the mediator class you want to be created.
+
+ mediatorMap.map(SomeType).toMediator(SomeMediator);
+
+ mediatorMap.mapMatcher(new TypeMatcher().anyOf(ISpaceShip, IRocket)).toMediator(SpaceCraftMediator);
+
+We provide a TypeMatcher and PackageMatcher. TypeMatcher has `allOf`, `noneOf`, `anyOf`. For more complex logic (equivalent of 'or') you can simply make multiple mappings. For more details on type and package matching, see:
+
+1. robotlegs.bender.extensions.matching.readme
+
+You can optionally add guards and hooks:
+
+ map(SomeClass).toMediator(SomeMediator).withGuards(NotOnTuesdays).withHooks(ApplySkin, UpdateLog);
+
+Guards and hooks can be passed as arrays or just a list of classes.
+
+Guards will be injected with the view to be mediated, and hooks can be injected with both the view and the mediator (these injections are then cleaned up so that mediators are not generally available for injection).
+
+For more information on guards and hooks check out:
+
+1. robotlegs.bender.framework.readme-guards
+2. robotlegs.bender.framework.readme-hooks
+
+### Removing mappings
+
+ mediatorMap.unmap(SomeClass).fromMediator(SomeMediator);
+
+ mediatorMap.unmapMatcher(someTypeMatcher).fromMediator(SomeMediator);
+
+ mediatorMap.unmap(SomeClass).fromMediators();
+
+### Mediating views automatically
+
+In Robotlegs 2, stage-event listening is centralised to a ViewManager. The ViewManager listens for views landing on the stage, and being removed from stage, and informs interested parties, such as the mediatorMap, accordingly.
+
+Assuming you're listening to your contextView, any view that lands on the contextView can be mediated if it matches a mapping you've already created.
+
+### Mediating objects manually
+
+The mediatorMap is able to mediate non-view objects. However, you'll need to implement your own strategy for deciding when these objects should be mediated and unmediated. Map your rules as normal, and then use:
+
+ mediatorMap.mediate(item);
+
+ mediatorMap.unmediate(item);
+
+### Packages excluded from automatic mediation
+
+For efficiency, classes from the following packages are excluded from automatic mediation:
+
+ flash
+ mx
+ spark
+
+### Flex specifics
+
+Flex UIComponents will have their mediators 'paused' until creationComplete has fired.
+
+### Reparenting
+
+When a view is reparented it fires both the remove and the added events. The mediator will be destroyed and then recreated. Any guards will be reapplied, and hooks will run again. You can guard against this situation in your hooks if it is potentially a problem (by keeping a cache of skinned views or checking some property on the view).
+
+### Unmapping does not equal unmediating
+
+Unmapping removes the rule. It will not destroy existing mediators related to that mapping. To remove mediators as well you'll need to unmediate the objects concerned manually.
+
+### Mapping and Unmapping is robust to redundancy
+
+- Duplicating an existing mapping, using the same guards and hooks, will not produce an error
+- Unmapping a mapping that does not exist will not produce an error
+- Repeating a mapping but with different guards and hooks will produce an error.
+ - if you use guards or hooks that were not previously used, the error is synchronous
+ - if you omit guards or hooks that were previous used, the error will happen as early as possible, which is the next time the mapping is used by the mediatorMap
+ - if you omit guards or hooks and this mapping is never used again, you will never see the error (but it shouldn't matter)
+
+## Mediators
+
+### Extend, follow convention, or bake your own
+
+Mediators should observe one of the following forms:
+
+1. Extend the base mediator class and override `initialize` and, if needed, `destroy`.
+ - If you override `destroy`, don't forget to call `super.destroy()` as this is where event listening cleanup is triggered.
+2. Don't extend the base mediator class, and provide functions `initialize()` and, if needed, also `destroy()`.
+3. Don't follow this convention, and use the `[PostConstruct]` metadata tag to ensure your initialization function is run
+ - note that this approach is not tailored for views extending Flex UIComponent, where initialization should be deferred until after creationComplete, so you will need to either provide for this in your implementation or use one of the methods above.
+
+### Mediator base class provides some useful functionality
+
+Mediator base class provides the following internal API, used for managing listeners and dispatching events.
+
+ addViewListener(eventString:String, listener:Function, eventClass:Class = null):void
+
+ addContextListener(eventString:String, listener:Function, eventClass:Class = null):void
+
+ removeViewListener(eventString:String, listener:Function, eventClass:Class = null):void
+
+ removeContextListener(eventString:String, listener:Function, eventClass:Class = null):void
+
+ dispatch(event:Event):void
+
+You can also access the injected `eventMap` directly, for example to listen to a subcomponent.
+
+For more details on the local eventMap see:
+
+1. robotlegs.bender.extensions.localEventMap.readme
View
2 src/robotlegs/bender/extensions/messageCommandMap/readme.md
@@ -34,7 +34,7 @@ This extension requires the following extensions:
Assuming that the MessageDispatcher and CommandMap extensions have already been installed:
- _context.require(MessageCommandMapExtension);
+ _context.extend(MessageCommandMapExtension);
## Extension Usage
View
6 src/robotlegs/bender/extensions/readme.md
@@ -96,7 +96,9 @@ The source for an extension should be packaged thusly:
impl
SuperDuper
-We can clearly spot the API, implementation and integration classes above.
+We can clearly spot the API, implementation and integration classes above.
+
+The api package should include any classes or interfaces that the typical user would come into contact with. The impl package contains classes that the typical user would not import.
## Unit Tests
@@ -108,6 +110,8 @@ The unit tests for an extension should be packaged thusly:
superDuper
SuperDuperExtensionTest
SuperDuperExtensionTestSuite
+ api
+ SuperDuperErrorTest
impl
SuperDuperTest
support

0 comments on commit 837f10c

Please sign in to comment.