refactor: input

This commit is contained in:
cha0s 2021-02-10 10:59:49 -06:00
parent b100b523f5
commit 28e5e9f56f
2 changed files with 103 additions and 11 deletions

View File

@ -1,6 +1,6 @@
import './index.scss';
import {ActionRegistry, InputNormalizer} from '@avocado/input';
import {InputNormalizer} from '@avocado/input';
import {setSelfEntity, useSelfEntity} from '@humus/core';
import {useDispatch} from '@latus/redux';
import {useSocket} from '@latus/socket';
@ -26,23 +26,18 @@ const Play = () => {
};
}, [dispatch, socket, uuid]);
useEffect(() => {
if (!ref.current) {
if (!ref.current || !selfEntity) {
return undefined;
}
const inputNormalizer = new InputNormalizer();
inputNormalizer.listen(window.document.body);
const actionRegistry = new ActionRegistry();
actionRegistry.setActionTransformerFor('UseItem', (type) => (
selfEntity && 'keyDown' === type ? selfEntity.activeSlotIndex : -1
selfEntity.listenForInput(inputNormalizer);
selfEntity.actionRegistry.setTransformerFor('UseItem', (type) => (
'keyDown' === type ? selfEntity.activeSlotIndex : -1
));
actionRegistry.listen(inputNormalizer);
const inputHandle = setInterval(() => {
const inputStream = actionRegistry.drain();
const inputStream = selfEntity.drainInput();
if (inputStream.length > 0) {
// Inject input.
if (selfEntity) {
selfEntity.inputStream = inputStream;
}
const sending = inputStream.filter(({action}) => {
if (action.match(/^HotbarSlot(\d)/)) {
return false;

View File

@ -2,6 +2,7 @@ import {
TickingPromise,
} from '@avocado/core';
import {Vector} from '@avocado/math';
import {ActionRegistry} from '@avocado/input';
import {Trait} from '@avocado/traits';
import {
compose,
@ -18,15 +19,85 @@ const decorate = compose(
// Input handling.
export default () => class Controllable extends decorate(Trait) {
#actionRegistry;
#itemPromise;
#itemUseRequest = -1;
#queued = [];
constructor() {
super();
this.on('controllableMovementChanged', this.updateAnimation, this);
}
get actionRegistry() {
return this.#actionRegistry;
}
static defaultParams() {
return {
actions: {
HotbarSlot0: [
{type: 'key', index: '1'},
],
HotbarSlot1: [
{type: 'key', index: '2'},
],
HotbarSlot2: [
{type: 'key', index: '3'},
],
HotbarSlot3: [
{type: 'key', index: '4'},
],
HotbarSlot4: [
{type: 'key', index: '5'},
],
HotbarSlot5: [
{type: 'key', index: '6'},
],
HotbarSlot6: [
{type: 'key', index: '7'},
],
HotbarSlot7: [
{type: 'key', index: '8'},
],
HotbarSlot8: [
{type: 'key', index: '9'},
],
HotbarSlot9: [
{type: 'key', index: '0'},
],
HotbarSlotNext: [
{type: 'key', index: 'WheelDown'},
],
HotbarSlotPrevious: [
{type: 'key', index: 'WheelUp'},
],
MoveUp: [
{type: 'key', index: 'w'},
],
MoveLeft: [
{type: 'key', index: 'a'},
],
MoveDown: [
{type: 'key', index: 's'},
],
MoveRight: [
{type: 'key', index: 'd'},
],
UseItem: [
{type: 'key', index: 'ArrowLeft'},
{type: 'button', index: 0},
],
Interact: [
{type: 'key', index: 'e'},
],
},
};
}
static dependencies() {
return [
'Animated',
@ -36,6 +107,10 @@ export default () => class Controllable extends decorate(Trait) {
];
}
destroy() {
this.#actionRegistry.stopListening();
}
set inputStream(inputStream) {
for (let i = 0; i < inputStream.length; i++) {
const {action, value} = inputStream[i];
@ -76,9 +151,31 @@ export default () => class Controllable extends decorate(Trait) {
async load(json) {
await super.load(json);
this.entity.on('isMobileChanged', this.updateAnimation, this);
this.#actionRegistry = new ActionRegistry(this.params.actions);
}
methods() {
return {
drainInput: () => {
const drained = this.#queued;
this.#queued = [];
return drained;
},
listenForInput: (inputNormalizer) => {
this.#actionRegistry.listen(inputNormalizer);
},
};
}
tick(elapsed) {
if ('client' === process.env.SIDE) {
const drained = this.#actionRegistry.drain();
this.inputStream = drained;
this.#queued.push(...drained);
}
if (-1 !== this.#itemUseRequest && !this.#itemPromise) {
this.#itemPromise = this.entity.useItemInSlot(this.#itemUseRequest);
Promise.resolve(this.#itemPromise).then(() => {