Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emit cancelable beforeMove event #182

Open
pedro-pedrosa opened this issue Mar 29, 2021 · 1 comment
Open

Emit cancelable beforeMove event #182

pedro-pedrosa opened this issue Mar 29, 2021 · 1 comment

Comments

@pedro-pedrosa
Copy link

I would like to be able to fully control the state of the board by being able to programmatically handle user move gestures myself. Currently the API doesn't allow this, as a user move gesture (click + click or drag + drop) first changes internal state and then emits the event.

This works fine until you want to handle promotions, puzzle fails, or interactive lessons because in order to cancel the move you have to revert to the previous state after the internal state has changed, causing a "backwards" animation on the moved piece. In promotions where you capture a piece it's even worse because you have to keep track of the captured piece in order to place it back on the board if the user cancels the promotion before selecting a new piece.

It would make sense to create a beforeMove or a userMoveGesture event which could be canceled, similar to DOM events e.preventDefault(). This would allow user code to apply logic to the move intent, and possibly then calling move if needed.

Adding this event is a non-breaking change and would only apply to user initiated moves, not programmatic moves. This also makes this library a lot more compatible with functional, declarative-first libraries like React and Vue, where emitting these "intent events" is the key concept for idiomatic code.

If this sounds good I'd be willing to create a PR with this change.

@avi-0
Copy link

avi-0 commented Jul 16, 2023

Would like to also mention previously closed #23

@ornicar

as the readme states, there's no chess logic inside chessground. I.E. chessground does not know the rules of chess. They have to be provided by a third party. You have to tell chessground to remove the taken pawn.

I just ran into an issue with that in my toy project where the en passant wouldn't trigger animations correctly: I move the pawn to the en passanted square, cg.State updates and starts an animation, then the victim pawn gets removed and the animation cancels immediately. This had to do with, afaik, the fact that I did this by having my callback in config.events.movable.after() set a piece of React state, which would propagate back to chessground later, when .after() has already finished and chessground has started animating.

Not that any of that is chessground's fault. The way I fixed that was to have .after immediately mutate the cg.State to undo the change and wait for the actual change to arrive later. Feels a bit hacky, not sure if that's the "intended" solution - the animation logic looks pretty mysterious to me.

But if that's all good, can't this issue be solved simply by legitimizing this hack, for example by allowing .after() (or whichever one) to return something like true or { cancel: true } so userMove undoes the state change?

...just realized callUserFunction doesnt actually wait for my function to finish and just gives it to setTimeout, why does my hack work then omg

anyways just food for thought

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants