Saving Config Changes

How could we extend the Config class to allow writing the configuration back to a file, effectively saving changes made in-game?

To enable saving the configuration back to a file, we need to add a Save() method to our Config class.

This method will do the reverse of Load(): it will take the current values of the Config object's members and write them to a file in the correct format.

Implementing Save()

Here's how we can implement the Save() method:

#include <SDL.h>
#include <iostream>
#include <string>
#include <vector>

class Config {
 public:
  std::string WindowTitle;
  int WindowWidth;
  int WindowHeight;
  std::vector<int> Levels;

  void Save(const std::string& Path) {
    SDL_RWops* File{SDL_RWFromFile(
      Path.c_str(), "w")};
    if (!File) {
      std::cout << "Failed to open config file "
        "for writing: " << SDL_GetError() << "\n";
      return;
    }

    std::string Content{""};
    Content += "WINDOW_TITLE: "
      + WindowTitle + "\n";
    Content += "WINDOW_WIDTH: "
      + std::to_string(WindowWidth) + "\n";
    Content += "WINDOW_HEIGHT: "
      + std::to_string(WindowHeight) + "\n";
    Content += "LEVELS: ";
    for (size_t i{0}; i < Levels.size(); ++i) {
      Content += std::to_string(Levels[i]);
      if (i < Levels.size() - 1) {
        Content += ",";
      }
    }
    Content += "\n";

    SDL_RWwrite(
      File,
      Content.c_str(),
      Content.size(),
      1
    );

    SDL_RWclose(File);
  }

}; int main() { Config MyConfig; MyConfig.WindowTitle = "My Awesome Game"; MyConfig.WindowWidth = 1024; MyConfig.WindowHeight = 768; MyConfig.Levels = {1, 2, 3, 4, 5}; MyConfig.Save("config.txt"); }
WINDOW_TITLE: My Awesome Game
WINDOW_WIDTH: 1024
WINDOW_HEIGHT: 768
LEVELS: 1,2,3,4,5

Explanation

  1. SDL_RWFromFile() for Writing: We use SDL_RWFromFile() with the "w" mode to open the file for writing. If the file doesn't exist, it will be created. If it does exist, it will be overwritten.
  2. Building the Content String: We create a std::string called Content and build it up line by line, using + to append each key-value pair. We use std::to_string() to convert numeric values to strings.
  3. SDL_RWwrite(): We use SDL_RWwrite() to write the entire Content string to the file.
  4. SDL_RWclose(): We close the file using SDL_RWclose().

Usage Example

In your game, you might modify the Config object's properties during gameplay (e.g., the player changes settings in a menu).

Then, you can call Save("config.txt") to save the updated configuration to the file, making the changes persistent across game sessions.

Parsing Data using std::string

Learn how to read, parse, and use config files in your game using std::string and SDL_RWops

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Moving Past Delimiters
Why do we use Start = End + 1 to move to the next position after finding a delimiter (like \n or ,)?
Trimming Extra Spaces
What if a key in our config file has multiple spaces before or after it, such as " KEY : VALUE"? How can we trim leading/trailing spaces from the key and value?
Config from Network Stream
What changes would be needed to load the config from a different source, like a network stream, instead of a file?
Implementing a Default Config
How could we implement a default configuration that is used if the config file is missing or invalid?
Error Line Numbers
When we encounter an error parsing a file, how can we output an error message that includes where the error occurred - for example, the line number within the file?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant