[rename fixit] GestureArena -> GestureArenaManager
Also, change the keys to be explicitly pointer ids. Fixes #202
This commit is contained in:
parent
5b383a0353
commit
44c4e930d1
@ -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 {
|
|||||||
///
|
///
|
||||||
/// 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 {
|
|||||||
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 {
|
|||||||
///
|
///
|
||||||
/// 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
|
|||||||
|
|
||||||
/// 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 {
|
|||||||
/// 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;
|
|||||||
|
|
||||||
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';
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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';
|
|||||||
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() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user