mliebelt / pgn-viewer

Simple PGN viewer with the necessary features to display chess games
GNU General Public License v3.0
161 stars 44 forks source link

What if my moves are coming from the backend in real time? #19

Open rohandalvi opened 8 years ago

rohandalvi commented 8 years ago

So lets say I am able to load the pgn initially and mine is a real time chess app, how do i refresh the view once i have a new move made on the board? Is there a way to hook it up with a real time backend?

Currently, i am using this library to display games that are being played elsewhere, everytime a move is made on the "playing" board, that move is notified to my app which is using this library and should be able to reflect that move dynamically. Is that possible using this lib?

mliebelt commented 8 years ago

I don't think it is possible at the moment. But as you may suspect, the edit mode of the application does something similar. I have to dig inside it. What would be the UI to do that? The edit mode does it in the UI (first) and then in the backend code, you need something that is triggered by the backend, and then reflected in the UI.

Is that a correct summary?

rohandalvi commented 8 years ago

Yes. For instance, if a player makes a move it is entered into a db. There is a listener attached that triggers when there is a new addition. This triggers a function call with the new move that needs to be reflected to the viewer viewing this game. I have the backend setup, just need a way to highlight that new move on the UI. Hope it makes sense.

mliebelt commented 8 years ago

In #20 @LocutusOfPenguin mentioned that he wants a similar functionality. At the moment, I try to find an example (with some small corrections) that will look like:

var pgn = "";
var cfg = { showNotation: false, position: 'start', pgn: pgn };
var board = pgnView('board', cfg);
var move = function (from, to) {
    setTimeout(function() {
        board.onDrop(from, to);
        board.onSnapEnd();
        setTimeout(function() {}(), 50)
    }(), 1000)
};
move("e2", "e4");
move("e7", "e5");
move("g1", "f3");
move("g8", "f6");
move("d2", "d4");

So you get the idea. The point here is that by one call (with arguments source and target) you could add moves to the end of the game. The edit functionality is not finished, so I do not know what will happen if you play through the game, and a new move drops in.

(All the timeout stuff should only simulate the delay between moves. And it does not work at the moment ... When I debug it, it works more or less, so perhaps it would be sufficient. If you know a nice way to simulate that to build a simple example, just drop me a link :-)

mliebelt commented 8 years ago

I have added some code so that it should be possible to use it now with a backend that delivers the newest moves. See my tries to create an example under [pgnAddMoves.html]https://github.com/mliebelt/PgnViewerJS/blob/master/examples/pgnAddMoves.html) (this only works when you clone the complete repository.

The base idea is the following code snippet:

var pgn = "";
var cfg = { locale: 'en', position: 'start', pgn: pgn };
var board = pgnView('board', cfg);
var move = function (from, to) {
      board.onDrop(from, to);
      board.onSnapEnd();
}
move("e2", "e4");
move("e7", "e5");
move("g1", "f3");
move("g8", "f6");
move("d2", "d4");

It is a pitty that is does not display the moves during they are done, only the result. I have not found any way to simulate that backend in one thread only, that is blocking the refresh of the UI.

So I leave that ticket open, please use the 2 function calls (onDrop, donSnapEnd) and try them out. And if you have an idea how to improve the example pgnAddMoves.html, I would glad to fix that.

LocutusOfPenguin commented 8 years ago

How about this? (im sure, there are better ways to do it - but for me it works):

var pgn = "";
var cfg = { locale: 'en', position: 'start', pgn: pgn };
var board = pgnView('board', cfg);
var move = function (from, to) {
    board.onDrop(from, to);
    board.onSnapEnd();
};

tasks = [
  function() {move("e2", "e4")},
  function() {move("e7", "e5")},
  function() {move("g1", "f3")},
  function() {move("g8", "f6")},
  function() {move("d2", "d4")}
];

function writeNext(i)
{
   var t = tasks[i];
   t();
  setTimeout(function()
  {
    if(i < tasks.length-1)
      writeNext(i + 1);
   }, 700);
} 
writeNext(0);
rohandalvi commented 8 years ago

@mliebelt I haven't tried this yet. I will try this approach in the next couple of days and let you know. Additionally, I'll try to find a better way to do this :-)

mliebelt commented 8 years ago

Had that evening the time to try that out, and it works like a charm, thank's a lot for the example code to @LocutusOfPenguin

nftechie commented 5 years ago

Is it possible to accomplish this by passing in an updated PGN? For example, the first time you load into the "board" div, you pass PGN_initial. Then, 5 minutes later, you update the "board" div with PGN_plus_3_moves. Could the library work out the differences and smoothly update? Right now, it flickers and reanimates.

nftechie commented 5 years ago

We have thought about trying to calculate a diff in the moves, and use the addMoves approach above. But if the moves ever get corrupted somehow, the state is probably not recoverable unless the user refreshes. We've also thought about having 2 boards, with one hidden in the background. And doing some delayed swapping of the boards, to make sure there is no flicker and reanimation. However, both of these approaches have drawbacks. I'm curious if you have any thoughts!

mliebelt commented 5 years ago

@awormuth Have you any example code that you could share? Some simple java script, an example HTML page? So I could have a look where the problem lays with the flicker and reanimation.

Currently there is no support for this. So if you want to have it, take at least the time to describe what you want to have:

Please add a new task for that, and I will have a look in my spare time. As you may have noticed, this ticket is ~ 3 years old, and I cannot even say if that approach would work now. But I am willing to give it a try ... ;-)

mliebelt commented 3 years ago

Is broken again, I should give it a try (again), if there is an easy fix available.