Improved input event handling
- Added Component.passInputToChildren() - Input events can now be processed in parallel or recursively
This commit is contained in:
parent
f350467942
commit
92f9639c4b
@ -562,6 +562,10 @@ public class Component extends Named {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean passInputToChildren(InputEvent e) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
InputBus getInputBus() {
|
InputBus getInputBus() {
|
||||||
return inputBus;
|
return inputBus;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
|||||||
import ru.windcorp.progressia.client.graphics.input.InputEvent;
|
import ru.windcorp.progressia.client.graphics.input.InputEvent;
|
||||||
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
|
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
|
||||||
import ru.windcorp.progressia.client.graphics.input.bus.InputBus;
|
import ru.windcorp.progressia.client.graphics.input.bus.InputBus;
|
||||||
|
import ru.windcorp.progressia.common.util.LowOverheadCache;
|
||||||
import ru.windcorp.progressia.common.util.StashingStack;
|
import ru.windcorp.progressia.common.util.StashingStack;
|
||||||
|
|
||||||
public abstract class GUILayer extends AssembledFlatLayer {
|
public abstract class GUILayer extends AssembledFlatLayer {
|
||||||
@ -75,9 +76,11 @@ public abstract class GUILayer extends AssembledFlatLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stack for {@link #handleInput(InputEvent)}.
|
* Stacks for {@link #handleInput(InputEvent)}.
|
||||||
*/
|
*/
|
||||||
private StashingStack<EventHandlingFrame> path = new StashingStack<>(64, EventHandlingFrame::new);
|
private final LowOverheadCache<StashingStack<EventHandlingFrame>> pathCache = new LowOverheadCache<>(
|
||||||
|
() -> new StashingStack<>(64, EventHandlingFrame::new)
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is essentially a depth-first iteration of the component tree. The
|
* This is essentially a depth-first iteration of the component tree. The
|
||||||
@ -85,10 +88,10 @@ public abstract class GUILayer extends AssembledFlatLayer {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void handleInput(InputEvent event) {
|
public void handleInput(InputEvent event) {
|
||||||
|
StashingStack<EventHandlingFrame> path = pathCache.grab();
|
||||||
|
|
||||||
if (!path.isEmpty()) {
|
if (!path.isEmpty()) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException("path is not empty: " + path);
|
||||||
"path is not empty: " + path + ". Are events being processed concurrently?"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
path.push().init(root);
|
path.push().init(root);
|
||||||
@ -101,7 +104,7 @@ public abstract class GUILayer extends AssembledFlatLayer {
|
|||||||
Component c = it.next();
|
Component c = it.next();
|
||||||
|
|
||||||
if (c.isEnabled()) {
|
if (c.isEnabled()) {
|
||||||
if (c.getChildren().isEmpty()) {
|
if (c.getChildren().isEmpty() || !c.passInputToChildren(event)) {
|
||||||
c.getInputBus().dispatch(event);
|
c.getInputBus().dispatch(event);
|
||||||
} else {
|
} else {
|
||||||
path.push().init(c);
|
path.push().init(c);
|
||||||
@ -114,6 +117,8 @@ public abstract class GUILayer extends AssembledFlatLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pathCache.release(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void attemptFocusTransfer(KeyEvent e) {
|
private void attemptFocusTransfer(KeyEvent e) {
|
||||||
|
Reference in New Issue
Block a user