0

I have the following struct:

typedef struct gameState {
    WINDOW *game;
    character *player;
    finalPosition positions[5];
    int level, found, timeSpent[3];
} gameState;

How can I save in the gameState.game a ncurses window?

This is how I created the window.

WINDOW * game = newwin(20, 50, 2, 2);

I think my problem is probably a pointer problem, I'm trying to save a pointer to a struct and whenever I leave the function that created this pointer, it deletes the content of which the pointer points to.

My final objective with this is to save the whole struct into a binary file. I know ncurses have the function putwin(), which saves a window to a binary file, but I need to save the window AND the rest of the content of this struct in the same binary file, so the putwin() doesn't solve my problem.

  • Your structure needs to be dynamically allocated if you initialize it in your function. Then assign its `game` variable as such `gameState->game = newwin(20, 50, 2, 2)` or `gameState->game = game`. – Ra'Jiska Jul 05 '17 at 15:58
  • 1
    Looks like XY-problem. Why do you want to save the window? It is a frontend. To save a game state you need to save the backend. – Eugene Sh. Jul 05 '17 at 15:59
  • @EugeneSh., I'll do that, thanks for the advice. – Daniel Novaes Jul 05 '17 at 16:39
  • Actually ncurses 6 stores the result in a (mostly) text-file. A common assumption for binary files is that the data uses fixed-size records... – Thomas Dickey Jul 05 '17 at 20:05

1 Answers1

0

Although it is quite likely that you would be better off serialising the state of the game which produces the window rather than the window itself, there is no problem using putwin and getwin to serialise and retrieve an ncurses Window.

putwin just writes a description of the window to the given FILE. It doesn't rewind the file stream, nor does it require it to be rewound. It doesn't close the file stream, either. Similarly, getwin just reads the window description from the given FILE starting at the current read point.

So you can use putwin/getwin as part of a serialisation procedure:

int serialiseWindow(Window* game, FILE* file) {
  return putwin(game, file);
}

int serialiseGameState(gameState *state, FILE* file) {
  int status;
  status = serialiseWindow(state->game, file);
  if (status != OK) return status;
  status = serialisePositionArray(state->positions,
                                  (sizeof state->positions)/(sizeof *state->positions),
                                  file);
  if (status != OK) return status;
  status = serialiseInteger(state->level, file);
  if (status != OK) return status;
  status = serialiseInteger(state->found, file);
  if (status != OK) return status;
  status = serialiseIntegerArray(state->timeSpent,
                                 (sizeof state->timeSpent)/(sizeof *state->timeSpent),
                                 file);
  return status;
}

And, to get it back:

int retrieveWindow(Window** game, FILE* file) {
  Window* win = getwin(file);
  *game = win;
  return win ? OK : ERR;
}

int retrieveGameState(gameState *state, FILE* file) {
  int status;
  status = retrieveWindow(&state->game, file);
  if (status != OK) return status;
  status = retrievePositionArray(state->positions,
                                 (sizeof state->positions)/(sizeof *state->positions),
                                 file);
  if (status != OK) return status;
  status = retrieveInteger(&state->level, file);
  if (status != OK) return status;
  status = retrieveInteger(&state->found, file);
  if (status != OK) return status;
  status = retrieveIntegerArray(state->timeSpent,
                                (sizeof state->timeSpent)/(sizeof *state->timeSpent),
                                file);
  return status;
}
rici
  • 234,347
  • 28
  • 237
  • 341