Skip to content

Commit 7a55fe5

Browse files
committed
Corrected disptaching of EntityMouseClick and EntityMouseDrag events
Previous version required that EntityMouseDown be supported and registered in order to receive EntityMouseClick or EntityMouseDrag events.
1 parent 8e7a048 commit 7a55fe5

File tree

1 file changed

+75
-36
lines changed

1 file changed

+75
-36
lines changed

Sources/Scenes/Dispatcher.swift

Lines changed: 75 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ public class Dispatcher {
3939
private var registeredEntityMouseUpHandlers = [EntityMouseUpHandler]()
4040
private var registeredEntityMouseClickHandlers = [EntityMouseClickHandler]()
4141
private var registeredEntityMouseDragHandlers = [EntityMouseDragHandler]()
42-
private var mostRecentEntityMouseDownHandler : EntityMouseDownHandler? = nil
42+
43+
// Keep track of the name for EntityMouseClick/EntityMouseDrag events
44+
private var mostRecentEntityNameForMouseClickOrDrag : String? = nil
4345

4446
// Mouse State
4547
private var previousMouseLocation : Point? = nil
@@ -148,8 +150,8 @@ public class Dispatcher {
148150
// Raise the event for entities
149151
raiseEntityMouseUpEvent(globalLocation:globalLocation)
150152

151-
// Clear the most recent entity mouseDown handler
152-
mostRecentEntityMouseDownHandler = nil
153+
// Clear the most recent name for handling clicks and drags
154+
mostRecentEntityNameForMouseClickOrDrag = nil
153155
}
154156

155157
// ========== WindowMouseUpHandler ==========
@@ -235,8 +237,8 @@ public class Dispatcher {
235237
}
236238

237239
internal func raiseEntityMouseDownEvent(globalLocation:Point) {
238-
// This is easy if there are no registered handlers
239-
if !registeredEntityMouseDownHandlers.isEmpty {
240+
// We only need to proceed if we have either EntityMouseDown, EntityMouseClick, or EntityMouseDrag handlers
241+
if !registeredEntityMouseDownHandlers.isEmpty || !registeredEntityMouseClickHandlers.isEmpty || !registeredEntityMouseDragHandlers.isEmpty {
240242
guard let director = director else {
241243
fatalError("raiseEntityMouseDownEvent requires a director")
242244
}
@@ -251,15 +253,39 @@ public class Dispatcher {
251253
// Otherwise, this is likely an error
252254
for entity in frontToBackList {
253255
if entity.hitTest(globalLocation:globalLocation) {
254-
let matchingRegisteredEntities = registeredEntityMouseDownHandlers.filter {$0.name == entity.name}
255-
precondition(matchingRegisteredEntities.count <= 1, "raiseEntityMouseDownEvent found non-unique entity names for '\(entity.name)'")
256-
if matchingRegisteredEntities.count == 1 {
257-
let handler = matchingRegisteredEntities[0]
256+
// Find a candidate for EntityMouseDown
257+
let matchingRegisteredMouseDownEntities = registeredEntityMouseDownHandlers.filter {$0.name == entity.name}
258+
precondition(matchingRegisteredMouseDownEntities.count <= 1, "raiseEntityMouseDownEvent found non-unique entity names for '\(entity.name) for EntityMouseDown'")
259+
260+
// Find a candidate for EntityMouseClick
261+
let matchingRegisteredMouseClickEntities = registeredEntityMouseClickHandlers.filter {$0.name == entity.name}
262+
precondition(matchingRegisteredMouseClickEntities.count <= 1, "raiseEntityMouseDownEvent found non-unique entity names for '\(entity.name)' for EntityMouseClick'")
263+
264+
// Find a candidate for EntityMouseDrag
265+
let matchingRegisteredMouseDragEntities = registeredEntityMouseDragHandlers.filter {$0.name == entity.name}
266+
precondition(matchingRegisteredMouseDragEntities.count <= 1, "raiseEntityMouseDownEvent found non-unique entity names for '\(entity.name)' for EntityMouseDrag")
267+
268+
// Track to see if we consume the event so that we can offer a helpful error message
269+
var eventWasConsumed = false
270+
271+
// Handle EntityMouseDown
272+
if matchingRegisteredMouseDownEntities.count == 1 {
273+
let handler = matchingRegisteredMouseDownEntities[0]
258274
handler.onEntityMouseDown(globalLocation:globalLocation)
259-
mostRecentEntityMouseDownHandler = handler
260-
} else {
261-
print("WARNING: hitTest for entity '\(entity.name)' intercepted hit for raiseEntityMouseDown event but is unregistered")
275+
eventWasConsumed = true
276+
}
277+
278+
// and/or handle EntityMouseDrag or EntityMouseClick
279+
if matchingRegisteredMouseClickEntities.count == 1 || matchingRegisteredMouseDragEntities.count == 1 {
280+
mostRecentEntityNameForMouseClickOrDrag = entity.name
281+
eventWasConsumed = true
282+
}
283+
284+
if !eventWasConsumed {
285+
print("WARNING: hitTest for entity '\(entity.name)' intercepted hit for raiseEntityMouseDown/Click/Drag event but is unregistered")
262286
}
287+
288+
// We only search for the top-most entity that has a hit-test that succeeds
263289
break
264290
}
265291
}
@@ -279,8 +305,8 @@ public class Dispatcher {
279305
}
280306

281307
internal func raiseEntityMouseUpEvent(globalLocation:Point) {
282-
// This is easy if there are no registered handlers
283-
if !registeredEntityMouseUpHandlers.isEmpty {
308+
// We only need to proceed if we have either EntityMouseUpHandlers or EntityMouseClickHandlers
309+
if !registeredEntityMouseUpHandlers.isEmpty || !registeredEntityMouseClickHandlers.isEmpty {
284310
guard let director = director else {
285311
fatalError("raiseEntityMouseUpEvent requires a director")
286312
}
@@ -295,16 +321,36 @@ public class Dispatcher {
295321
// Otherwise, this is likely an error
296322
for entity in frontToBackList {
297323
if entity.hitTest(globalLocation:globalLocation) {
298-
let matchingRegisteredEntities = registeredEntityMouseUpHandlers.filter {$0.name == entity.name}
299-
precondition(matchingRegisteredEntities.count <= 1, "raiseEntityMouseUpEvent found non-unique entity names for '\(entity.name)'")
300-
if matchingRegisteredEntities.count == 1 {
301-
let handler = matchingRegisteredEntities[0]
324+
// Find a candidate for EntityMouseUp
325+
let matchingRegisteredMouseUpEntities = registeredEntityMouseUpHandlers.filter {$0.name == entity.name}
326+
precondition(matchingRegisteredMouseUpEntities.count <= 1, "raiseEntityMouseUpEvent found non-unique entity names for '\(entity.name)' for EntityMouseUp")
327+
328+
// Track to see if we consume the event so that we can offer a helpful error message
329+
var wasEventConsumed = false
330+
331+
// Handle EntityMouseClick
332+
if let mostRecentEntityNameForMouseClickOrDrag = mostRecentEntityNameForMouseClickOrDrag,
333+
entity.name == mostRecentEntityNameForMouseClickOrDrag {
334+
// Find a candiate for EntityMouseClick
335+
let matchingRegisteredMouseClickEntities = registeredEntityMouseClickHandlers.filter {$0.name == entity.name}
336+
precondition(matchingRegisteredMouseClickEntities.count <= 1, "raiseEntityMouseUpEvent found non-unique entity names for '\(entity.name)' for EntityMouseClick")
337+
338+
if matchingRegisteredMouseClickEntities.count == 1 {
339+
let handler = matchingRegisteredMouseClickEntities[0]
340+
handler.onEntityMouseClick(globalLocation:globalLocation)
341+
wasEventConsumed = true
342+
}
343+
}
344+
345+
// and/or Handle EntityMouseUp
346+
if matchingRegisteredMouseUpEntities.count == 1 {
347+
let handler = matchingRegisteredMouseUpEntities[0]
302348
handler.onEntityMouseUp(globalLocation:globalLocation)
349+
wasEventConsumed = true
350+
}
303351

304-
// Raise a click event for this entity
305-
raiseEntityMouseClickEvent(globalLocation:globalLocation, entityMouseUpHandler:handler)
306-
} else {
307-
print("WARNING: hitTest for entity '\(entity.name)' intercepted hit for raiseEntityMouseUp event but is unregistered")
352+
if !wasEventConsumed {
353+
print("WARNING: hitTest for entity '\(entity.name)' intercepted hit for raiseEntityMouseUp/Click event but is unregistered")
308354
}
309355
break
310356
}
@@ -325,18 +371,11 @@ public class Dispatcher {
325371
registeredEntityMouseClickHandlers.removeAll(where: {$0.name == handler.name})
326372
}
327373

374+
/* NOTE: This event is raised by raiseEntityMouseUpEvent
328375
internal func raiseEntityMouseClickEvent(globalLocation:Point, entityMouseUpHandler:EntityMouseUpHandler) {
329-
// This is easy if there are no registered handlers or if the upHandler was different than the downHandler
330-
if let mostRecentEntityMouseDownHandler = mostRecentEntityMouseDownHandler,
331-
!registeredEntityMouseClickHandlers.isEmpty && (mostRecentEntityMouseDownHandler.name == entityMouseUpHandler.name) {
332-
let matchingRegisteredEntities = registeredEntityMouseClickHandlers.filter {$0.name == entityMouseUpHandler.name}
333-
precondition(matchingRegisteredEntities.count <= 1, "raiseEntityMouseClickEvent found non-unique entity names for '\(entityMouseUpHandler.name)'")
334-
if matchingRegisteredEntities.count == 1 {
335-
let handler = matchingRegisteredEntities[0]
336-
handler.onEntityMouseClick(globalLocation:globalLocation)
337-
}
338-
}
376+
339377
}
378+
*/
340379

341380
// ========== EntityMouseDragHandler ==========
342381
public func registerEntityMouseDragHandler(handler:EntityMouseDragHandler) {
@@ -350,11 +389,11 @@ public class Dispatcher {
350389
}
351390

352391
internal func raiseEntityMouseDragEvent(globalLocation:Point, movement:Point) {
353-
// This is easy if there are no registered handlers or if there's no moseRecentEntityMouseDownHandler
354-
if let mostRecentEntityMouseDownHandler = mostRecentEntityMouseDownHandler,
392+
// This is easy if there is not a mostRecentEntityNameFrMouseClickOrDrag or there are no registered handlers
393+
if let mostRecentEntityNameForMouseClickOrDrag = mostRecentEntityNameForMouseClickOrDrag,
355394
!registeredEntityMouseDragHandlers.isEmpty {
356-
let matchingRegisteredEntities = registeredEntityMouseDragHandlers.filter {$0.name == mostRecentEntityMouseDownHandler.name}
357-
precondition(matchingRegisteredEntities.count <= 1, "raiseEntityMouseDragEvent found non-unique entity names for '\(mostRecentEntityMouseDownHandler.name)'")
395+
let matchingRegisteredEntities = registeredEntityMouseDragHandlers.filter {$0.name == mostRecentEntityNameForMouseClickOrDrag}
396+
precondition(matchingRegisteredEntities.count <= 1, "raiseEntityMouseDragEvent found non-unique entity names for '\(mostRecentEntityNameForMouseClickOrDrag)'")
358397
if matchingRegisteredEntities.count == 1 {
359398
let handler = matchingRegisteredEntities[0]
360399
handler.onEntityMouseDrag(globalLocation:globalLocation, movement:movement)

0 commit comments

Comments
 (0)