Commit 44c4e930 authored by Adam Barth's avatar Adam Barth

[rename fixit] GestureArena -> GestureArenaManager

Also, change the keys to be explicitly pointer ids.

Fixes #202
parent 5b383a03
...@@ -15,38 +15,38 @@ enum GestureDisposition { ...@@ -15,38 +15,38 @@ enum GestureDisposition {
/// ///
/// Receives callbacks from the GestureArena to notify the object when it wins /// Receives callbacks from the GestureArena to notify the object when it wins
/// or loses a gesture negotiation. Exactly one of [acceptGesture] or /// or loses a gesture negotiation. Exactly one of [acceptGesture] or
/// [rejectGesture] will be called for each arena key this member was added to, /// [rejectGesture] will be called for each arena this member was added to,
/// regardless of what caused the arena to be resolved. For example, if a /// regardless of what caused the arena to be resolved. For example, if a
/// member resolves the arena itself, that member still receives an /// member resolves the arena itself, that member still receives an
/// [acceptGesture] callback. /// [acceptGesture] callback.
abstract class GestureArenaMember { abstract class GestureArenaMember {
/// Called when this member wins the arena for the given key. /// Called when this member wins the arena for the given pointer id.
void acceptGesture(Object key); void acceptGesture(int pointer);
/// Called when this member loses the arena for the given key. /// Called when this member loses the arena for the given pointer id.
void rejectGesture(Object key); void rejectGesture(int pointer);
} }
/// An interface to information to an arena. /// An interface to information to an arena.
/// ///
/// A given [GestureArenaMember] can have multiple entries in multiple arenas /// A given [GestureArenaMember] can have multiple entries in multiple arenas
/// with different keys. /// with different pointer ids.
class GestureArenaEntry { class GestureArenaEntry {
GestureArenaEntry._(this._arena, this._key, this._member); GestureArenaEntry._(this._arena, this._pointer, this._member);
final GestureArena _arena; final GestureArenaManager _arena;
final Object _key; final int _pointer;
final GestureArenaMember _member; final GestureArenaMember _member;
/// Call this member to claim victory (with accepted) or admit defeat (with rejected). /// Call this member to claim victory (with accepted) or admit defeat (with rejected).
/// ///
/// It's fine to attempt to resolve an arena that is already resolved. /// It's fine to attempt to resolve an arena that is already resolved.
void resolve(GestureDisposition disposition) { void resolve(GestureDisposition disposition) {
_arena._resolve(_key, _member, disposition); _arena._resolve(_pointer, _member, disposition);
} }
} }
class _GestureArenaState { class _GestureArena {
final List<GestureArenaMember> members = new List<GestureArenaMember>(); final List<GestureArenaMember> members = new List<GestureArenaMember>();
bool isOpen = true; bool isOpen = true;
bool isHeld = false; bool isHeld = false;
...@@ -68,30 +68,30 @@ class _GestureArenaState { ...@@ -68,30 +68,30 @@ class _GestureArenaState {
/// ///
/// See [https://flutter.io/gestures/#gesture-disambiguation] for more /// See [https://flutter.io/gestures/#gesture-disambiguation] for more
/// information about the role this class plays in the gesture system. /// information about the role this class plays in the gesture system.
class GestureArena { class GestureArenaManager {
final Map<Object, _GestureArenaState> _arenas = new Map<Object, _GestureArenaState>(); final Map<int, _GestureArena> _arenas = new Map<int, _GestureArena>();
/// Adds a new member (e.g., gesture recognizer) to the arena. /// Adds a new member (e.g., gesture recognizer) to the arena.
GestureArenaEntry add(Object arenaKey, GestureArenaMember member) { GestureArenaEntry add(int pointer, GestureArenaMember member) {
_GestureArenaState state = _arenas.putIfAbsent(arenaKey, () => new _GestureArenaState()); _GestureArena state = _arenas.putIfAbsent(pointer, () => new _GestureArena());
state.add(member); state.add(member);
return new GestureArenaEntry._(this, arenaKey, member); return new GestureArenaEntry._(this, pointer, member);
} }
/// Prevents new members from entering the arena. /// Prevents new members from entering the arena.
/// ///
/// Called after the framework has finished dispatching the pointer down event. /// Called after the framework has finished dispatching the pointer down event.
void close(Object arenaKey) { void close(int pointer) {
_GestureArenaState state = _arenas[arenaKey]; _GestureArena state = _arenas[pointer];
if (state == null) if (state == null)
return; // This arena either never existed or has been resolved. return; // This arena either never existed or has been resolved.
state.isOpen = false; state.isOpen = false;
_tryToResolveArena(arenaKey, state); _tryToResolveArena(pointer, state);
} }
/// Forces resolution of the arena, giving the win to the first member. /// Forces resolution of the arena, giving the win to the first member.
void sweep(Object arenaKey) { void sweep(int pointer) {
_GestureArenaState state = _arenas[arenaKey]; _GestureArena state = _arenas[pointer];
if (state == null) if (state == null)
return; // This arena either never existed or has been resolved. return; // This arena either never existed or has been resolved.
assert(!state.isOpen); assert(!state.isOpen);
...@@ -99,19 +99,19 @@ class GestureArena { ...@@ -99,19 +99,19 @@ class GestureArena {
state.hasPendingSweep = true; state.hasPendingSweep = true;
return; // This arena is being held for a long-lived member return; // This arena is being held for a long-lived member
} }
_arenas.remove(arenaKey); _arenas.remove(pointer);
if (state.members.isNotEmpty) { if (state.members.isNotEmpty) {
// First member wins // First member wins
state.members.first.acceptGesture(arenaKey); state.members.first.acceptGesture(pointer);
// Give all the other members the bad news // Give all the other members the bad news
for (int i = 1; i < state.members.length; i++) for (int i = 1; i < state.members.length; i++)
state.members[i].rejectGesture(arenaKey); state.members[i].rejectGesture(pointer);
} }
} }
/// Prevents the arena from being swept. /// Prevents the arena from being swept.
void hold(Object key) { void hold(int pointer) {
_GestureArenaState state = _arenas[key]; _GestureArena state = _arenas[pointer];
if (state == null) if (state == null)
return; // This arena either never existed or has been resolved. return; // This arena either never existed or has been resolved.
state.isHeld = true; state.isHeld = true;
...@@ -121,58 +121,58 @@ class GestureArena { ...@@ -121,58 +121,58 @@ class GestureArena {
/// ///
/// If a sweep was attempted on a held arena, the sweep will be done /// If a sweep was attempted on a held arena, the sweep will be done
/// on release. /// on release.
void release(Object arenaKey) { void release(int pointer) {
_GestureArenaState state = _arenas[arenaKey]; _GestureArena state = _arenas[pointer];
if (state == null) if (state == null)
return; // This arena either never existed or has been resolved. return; // This arena either never existed or has been resolved.
state.isHeld = false; state.isHeld = false;
if (state.hasPendingSweep) if (state.hasPendingSweep)
sweep(arenaKey); sweep(pointer);
} }
void _tryToResolveArena(Object arenaKey, _GestureArenaState state) { void _tryToResolveArena(int pointer, _GestureArena state) {
assert(_arenas[arenaKey] == state); assert(_arenas[pointer] == state);
assert(!state.isOpen); assert(!state.isOpen);
if (state.members.length == 1) { if (state.members.length == 1) {
_arenas.remove(arenaKey); _arenas.remove(pointer);
state.members.first.acceptGesture(arenaKey); state.members.first.acceptGesture(pointer);
} else if (state.members.isEmpty) { } else if (state.members.isEmpty) {
_arenas.remove(arenaKey); _arenas.remove(pointer);
} else if (state.eagerWinner != null) { } else if (state.eagerWinner != null) {
_resolveInFavorOf(arenaKey, state, state.eagerWinner); _resolveInFavorOf(pointer, state, state.eagerWinner);
} }
} }
void _resolve(Object arenaKey, GestureArenaMember member, GestureDisposition disposition) { void _resolve(int pointer, GestureArenaMember member, GestureDisposition disposition) {
_GestureArenaState state = _arenas[arenaKey]; _GestureArena state = _arenas[pointer];
if (state == null) if (state == null)
return; // This arena has already resolved. return; // This arena has already resolved.
assert(state.members.contains(member)); assert(state.members.contains(member));
if (disposition == GestureDisposition.rejected) { if (disposition == GestureDisposition.rejected) {
state.members.remove(member); state.members.remove(member);
member.rejectGesture(arenaKey); member.rejectGesture(pointer);
if (!state.isOpen) if (!state.isOpen)
_tryToResolveArena(arenaKey, state); _tryToResolveArena(pointer, state);
} else { } else {
assert(disposition == GestureDisposition.accepted); assert(disposition == GestureDisposition.accepted);
if (state.isOpen) { if (state.isOpen) {
state.eagerWinner ??= member; state.eagerWinner ??= member;
} else { } else {
_resolveInFavorOf(arenaKey, state, member); _resolveInFavorOf(pointer, state, member);
} }
} }
} }
void _resolveInFavorOf(Object arenaKey, _GestureArenaState state, GestureArenaMember member) { void _resolveInFavorOf(int pointer, _GestureArena state, GestureArenaMember member) {
assert(state == _arenas[arenaKey]); assert(state == _arenas[pointer]);
assert(state != null); assert(state != null);
assert(state.eagerWinner == null || state.eagerWinner == member); assert(state.eagerWinner == null || state.eagerWinner == member);
assert(!state.isOpen); assert(!state.isOpen);
_arenas.remove(arenaKey); _arenas.remove(pointer);
for (GestureArenaMember rejectedMember in state.members) { for (GestureArenaMember rejectedMember in state.members) {
if (rejectedMember != member) if (rejectedMember != member)
rejectedMember.rejectGesture(arenaKey); rejectedMember.rejectGesture(pointer);
} }
member.acceptGesture(arenaKey); member.acceptGesture(pointer);
} }
} }
...@@ -48,7 +48,7 @@ abstract class Gesturer extends BindingBase implements HitTestTarget, HitTestabl ...@@ -48,7 +48,7 @@ abstract class Gesturer extends BindingBase implements HitTestTarget, HitTestabl
/// The gesture arenas used for disambiguating the meaning of sequences of /// The gesture arenas used for disambiguating the meaning of sequences of
/// pointer events. /// pointer events.
final GestureArena gestureArena = new GestureArena(); final GestureArenaManager gestureArena = new GestureArenaManager();
/// State for all pointers which are currently down. /// State for all pointers which are currently down.
/// ///
......
...@@ -31,7 +31,7 @@ abstract class GestureRecognizer extends GestureArenaMember { ...@@ -31,7 +31,7 @@ abstract class GestureRecognizer extends GestureArenaMember {
/// It's the GestureRecognizer's responsibility to then add itself /// It's the GestureRecognizer's responsibility to then add itself
/// to the global pointer router (see [PointerRouter]) to receive /// to the global pointer router (see [PointerRouter]) to receive
/// subsequent events for this pointer, and to add the pointer to /// subsequent events for this pointer, and to add the pointer to
/// the global gesture arena manager (see [GestureArena]) to track /// the global gesture arena manager (see [GestureArenaManager]) to track
/// that pointer. /// that pointer.
void addPointer(PointerDownEvent event); void addPointer(PointerDownEvent event);
......
...@@ -11,19 +11,19 @@ const int primaryKey = 4; ...@@ -11,19 +11,19 @@ const int primaryKey = 4;
class TestGestureArenaMember extends GestureArenaMember { class TestGestureArenaMember extends GestureArenaMember {
bool acceptRan = false; bool acceptRan = false;
void acceptGesture(Object key) { void acceptGesture(int key) {
expect(key, equals(primaryKey)); expect(key, equals(primaryKey));
acceptRan = true; acceptRan = true;
} }
bool rejectRan = false; bool rejectRan = false;
void rejectGesture(Object key) { void rejectGesture(int key) {
expect(key, equals(primaryKey)); expect(key, equals(primaryKey));
rejectRan = true; rejectRan = true;
} }
} }
class GestureTester { class GestureTester {
GestureArena arena = new GestureArena(); GestureArenaManager arena = new GestureArenaManager();
TestGestureArenaMember first = new TestGestureArenaMember(); TestGestureArenaMember first = new TestGestureArenaMember();
TestGestureArenaMember second = new TestGestureArenaMember(); TestGestureArenaMember second = new TestGestureArenaMember();
......
...@@ -9,10 +9,10 @@ import 'package:test/test.dart'; ...@@ -9,10 +9,10 @@ import 'package:test/test.dart';
import 'gesture_tester.dart'; import 'gesture_tester.dart';
class TestGestureArenaMember extends GestureArenaMember { class TestGestureArenaMember extends GestureArenaMember {
void acceptGesture(Object key) { void acceptGesture(int key) {
accepted = true; accepted = true;
} }
void rejectGesture(Object key) { void rejectGesture(int key) {
rejected = true; rejected = true;
} }
bool accepted = false; bool accepted = false;
......
...@@ -12,7 +12,7 @@ void main() { ...@@ -12,7 +12,7 @@ void main() {
setUp(ensureGesturer); setUp(ensureGesturer);
test('Should recognize scale gestures', () { test('Should recognize scale gestures', () {
GestureArena gestureArena = Gesturer.instance.gestureArena; GestureArenaManager gestureArena = Gesturer.instance.gestureArena;
PointerRouter pointerRouter = Gesturer.instance.pointerRouter; PointerRouter pointerRouter = Gesturer.instance.pointerRouter;
ScaleGestureRecognizer scale = new ScaleGestureRecognizer(); ScaleGestureRecognizer scale = new ScaleGestureRecognizer();
TapGestureRecognizer tap = new TapGestureRecognizer(); TapGestureRecognizer tap = new TapGestureRecognizer();
......
...@@ -12,7 +12,7 @@ void main() { ...@@ -12,7 +12,7 @@ void main() {
setUp(ensureGesturer); setUp(ensureGesturer);
test('Should recognize pan', () { test('Should recognize pan', () {
GestureArena gestureArena = Gesturer.instance.gestureArena; GestureArenaManager gestureArena = Gesturer.instance.gestureArena;
PointerRouter pointerRouter = Gesturer.instance.pointerRouter; PointerRouter pointerRouter = Gesturer.instance.pointerRouter;
PanGestureRecognizer pan = new PanGestureRecognizer(); PanGestureRecognizer pan = new PanGestureRecognizer();
TapGestureRecognizer tap = new TapGestureRecognizer(); TapGestureRecognizer tap = new TapGestureRecognizer();
......
...@@ -9,8 +9,8 @@ import 'package:test/test.dart'; ...@@ -9,8 +9,8 @@ import 'package:test/test.dart';
import 'gesture_tester.dart'; import 'gesture_tester.dart';
class TestGestureArenaMember extends GestureArenaMember { class TestGestureArenaMember extends GestureArenaMember {
void acceptGesture(Object key) {} void acceptGesture(int key) {}
void rejectGesture(Object key) {} void rejectGesture(int key) {}
} }
void main() { void main() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment