-
Notifications
You must be signed in to change notification settings - Fork 44
API and Callbacks for reader and viewer
There are many tickets that touch the topic of the API. Here is an (incomplete) list for some details:
- #175: Definition of useful external API
- #266: How to get current move? How to get current board?
- #176: Allow notification to PgnViewerJS
and many more. What is the problem?
By using the base API, it is not at all obvious how to use it programmatically besides constructing a board, viewer or editor. The API currently provided may help in implementing additional functionality, but not in just using the viewer as a library, that provides a useful API that can be used directly.
- Collect the most basic API that should be available.
- Do that for the reader (first) and the viewer (second).
- The reader could then be used inside node.js, and play e.g. through PGN, and asking the reader any time necessary information. So others could use the reader alone, to construct a new viewer without any change necessary.
- Compare the future API with the current one, and define how to come from current to future.
- Define events that are reasonable to be interested in.
- Define for those callback possibilities, that can be used by the user.
The reader API is developed in the new repo pgn-reader, but the requirements of that API are documented here. From the perspective of the viewer, the reader
- must ensure that the PGN / file is correctly read
- provides a sufficient API to play through the moves then XOR to allow adding new moves/comments/NAGs/... to the PGN while editing it.
- Change: the reader should be responsible for only one game at a time, so all APIs to manage the games will be removed
- split the viewer and editor API
Check the relevant parts of the reader for having the concrete API:
- Extract from the reader the current exported functions ✔️
- Go through each of them on the usage side (viewer) and comment on it (done in file
api-comments.md
) ✔️ - Restructure the remaining functions, to get a more clean API.
I would like to have different APIs depending on the mode
the viewer is in. In the long run, it would be nice to have a wrapper object, which is automatically built by calling the (currently) 4 base modes: pgnBoard
, pgnPrint
, pgnView
and pgnEdit
.
Before doing it concrete in the table, here a new try to isolate the interesting parts:
- read(config): should read a PGN / file, there may be variants for readGame, readGames. Focus here is to read the pgn, check the moves, build the static structure of the moves, and return that structure then. This is the requirement to
pgn-reader
, so not built in the viewer then.- parse(pgn|file, config): first step, calls the parser, not too much additionally.
- check(game, config): validates the game read, converts the game into something that then can be played/edited.
- view(game, config): returns something, that has then the right API to play the game in the viewer.
- setPosition(fen): search in the moves for the first position that matches the fen.
- makeMove(san): search in the moves the position, where that move was done. Make that move then. Error if move cannot be found.
- edit(game): returns something, that allows to edit then the game based on the given game. Similar to view, but some of the API calls will work different.
The problem I have to solve is, how state is handled here. When a move is made, it is known to the viewer what the current position is. So the state that is known is:
-
PgnGame
: tags, gameComment and moves
The following is a trial, how to structure it, so that it can be written and changed, and is readable.
API | Description | Modes |
---|---|---|
changeConfig(<Map<Key,Value>>):PgnViewerConfiguration |
Allows to change the currently existing configuration. This will then be merged with the current configuration. New values overwrite existing ones then. For the viewer, the current position will be restored (setPosition ), for the editor, the current PGN will replace the one given in the original configuration. Returns the merged configuration. |
all |
getConfig():PgnViewerConfiguration |
Returns the current configuration of the viewer. | all |
getPosition():FEN |
Returns the current position as FEN string. | board, view, edit |
setPosition(<FEN|number>):Move|null |
Sets the current position of the board. Depending on the mode, this may have a different effect: board --> just show that position; view, edit --> see if one of the moves leads to that position, and go to that. If the argument is a number, it is the move number of the main line, starting with 0. Returns the move that is done then on the board (null for the board). | board, view, edit |
move(<Move>):PgnReaderMove |
From the current position, try to do that move. Be flexible in the representation for the move. Returns the generated (or existing) move that was then played on the board. Returns null in case of an error. | view, edit |
getReader():PgnReader |
Returns the pgn-reader that is used by the viewer. May be necessary to have more control over chess capabilities. | board, view, edit |
getChess():Chess |
Chess object, to have some chess capabilities not given by the reader. | |
startTimer() |
Starts the timer of the viewer. | view, edit |
stopTimer() |
Stops the timer of the viewer. | view, edit |
-
setPosition
is similar tomakeMove
, which is really complicated, and will not work with the number of different arguments you can try. This would be the chance to change that API to something much simpler.
For notifications, I will try to do a similar approach. Collect possible events and callbacks, and describe for each how they could be used. They should as well depend on the mode that is used.
Event | Description | Modes |
---|---|---|
afterMove |
Inform the listener about a move done. The move itself will be part of the event. | view, edit |
afterChangeConfig |
Inform about a change in the configuration. Give the changes as argument. | board, view, edit |