!! WARNING: in progress...
# MMO.core.Map
This specific object is an extension of the native object `Map`. It allows event to be triggered whenever the map is changed.
## Principle
When the map is changed, these actions are taken:
1. Starting from the map being changed, we register all its listeners for the changes (keys events first)
2. We look for all its parents and repeat the first step with all of them
3. Repeat until there is no more parents.
4. In case a loop is discovered we stop there.
## Symbol Events
These events are triggered with the symbol. The first argument (map) is the current map on which the event is triggered.
- `MMO.core.MAP_CHANGED`: function ( MMO.core.MAP_CHANGED, map). Emitted when the map is changed in any way.
- `MMO.core.MAP_VALUE_CREATED`: function ( MMO.core.MAP_VALUE_CREATED, map, key, <*> value). Emitted when a value is created at a given key.
- `MMO.core.MAP_VALUE_DELETED`: function ( MMO.core.MAP_VALUE_DELETED, map, key, <*> value). Emitted when a value is deleted at a given key.
## Key events
These events are triggered with the key. type is the keyword listed at the beginning of each line.
- `MMO.core.MAP_VALUE_CHANGED`: function ( MMO.core.MAP_VALUE_CHANGED, map, key). Emitted at the key when the value is changed.
- `MMO.core.MAP_INDEX_CHANGED`: function ( MMO.core.MAP_INDEX_CHANGED, map, key). Emitted at the key when the index of a key is changed (`{a:1, b:2}` => `{b:2, a:1}`)
- `MMO.core.MAP_KEY_SWAP`: function ( MMO.core.MAP_KEY_SWAP, map, oldKey, newKey). Emitted only in lists at the old index (`[a,b]` => `[b,a]`)
List are specifics objects: `[a,b]` <=> `{0:a, 1:b}`
## Change events steps
- Change value: `{a: 1}` => `{a: 2}`
1. `map.emitAsync('a', MMO.core.MAP_VALUE_CHANGED, map, 'a')`
2. `map.emitAsync(MMO.core.MAP_CHANGED, map)`
3. for all parents, repeat change value steps with the `key = parent.keyOf(map)` and `map = parent(map)`
- Create value: `{}` => `{a:1}`
1. `map.emitAsync(MMO.core.MAP_VALUE_CREATED, map, 'a')`
2. for all parents, `parent.emitAsync(MMO.core.MAP_VALUE_CREATED, parent, parent.pathOf(map))`
3. do "change value" steps
- Delete value: `{a:2}` => `{}`
1. `map.emitAsync(MMO.core.MAP_VALUE_DELETED, map, 'a')`
2. for all parents, `parent.emitAsync(MMO.core.MAP_VALUE_DELETED, parent, parent.pathOf(map))`
3. do "change value" steps
- Sort keys: `{a: 1, b: 2}` => `{b: 2, a: 1}`
1. `map.emitAsync('a', MMO.core.MAP_INDEX_CHANGED, map, 'a')`
2. `map.emitAsync('b', MMO.core.MAP_INDEX_CHANGED, map, 'b')`
3. `map.emitAsync(MMO.core.MAP_CHANGED, map)`
- Sort values: `[a,b]` => `[b,a]`
1. `map.emitAsync(0, MMO.core.MAP_KEY_SWAP, map, 0, 1)`
2. `map.emitAsync(1, MMO.core.MAP_KEY_SWAP, map, 1, 0)`
3. `map.emitAsync(MMO.core.MAP_CHANGED, map)`