init.hpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#pragma once


#include <planet/audio/channel.hpp>
#include <planet/folders.hpp>
#include <planet/log.hpp>
#include <planet/serialise/forward.hpp>
#include <planet/telemetry/counter.hpp>
#include <planet/sdl/ttf.hpp>
#include <planet/version.hpp>

#include <felspar/io.hpp>

#include <fstream>


namespace planet::sdl {

Engine configuration

This configuraiton is only used for the save folder and the configuration save path. All other game configuration is managed by the game itself.

File logging will be automatically turned on.

27
28
    struct configuration final {
        static constexpr std::string_view box{"_p:sdl:config"};

Creation

32
33
        configuration(version const &);
        ~configuration();

File configuration

File configuration is calculated when the configuration object is created, but may be altered later using the set_game_folder method later on if the initial configuration is no good (this can happen on platforms like Android where the correct writeable folder is known too late).

Game folder

The game should use this folder to save any data that it may need to persist. There are specific files and folders below for configuration, logs and game saves.

52
        std::filesystem::path game_folder;

Changing the game folder

On some platforms it may not be possible to reliably determine the folder name at start up. For those this method should be called so that the folder structure can be determined.

60
        void set_game_folder(std::filesystem::path);

Configuration file name

63
        std::filesystem::path config_filename;

Save game folder

65
        std::filesystem::path save_folder;

Logging

68
69
70
        std::filesystem::path log_folder;
        std::optional<std::filesystem::path> log_filename, perf_filename;
        std::ofstream logfile, perfile;

User's configuration

74
75
76
77
        log::level log_level = log::level::debug;
        bool save_logs_to_file = true;
        bool auto_remove_log_files = true;
        bool upload_performance_data = true;

Audio configuration

81
82
83
84
        std::optional<std::string> audio_device_name = {};
        audio::channel master_volume{audio::dB_gain{-9}};
        audio::channel music_volume{audio::dB_gain{-15}};
        audio::channel sfx_volume{audio::dB_gain{-3}};

Performance counters

88
89
90
91
92
        telemetry::counter times_exited = {"planet_sdl_config_times_exited", 0};
        telemetry::counter times_loaded = {"planet_sdl_config_times_loaded", 1};
    };
    void save(serialise::save_buffer &, configuration const &);
    void load(serialise::load_buffer &, configuration &);

Engine initialisation

96
97
    class init final {
      public:

Pass the application name which is used to generate the configuration paths

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
        init(felspar::io::warden &w, version const &);
        ~init();

        configuration config;
        felspar::io::warden &io;


        template<typename F, typename... Args>
        felspar::coro::task<int> run(felspar::io::warden &, F f, Args... args) {
            co_return co_await f(*this, std::forward<Args>(args)...);
        }


        std::span<std::string const> audio_devices() const noexcept {
            return audio_device_list;
        }


      private:
        std::vector<std::string> audio_device_list;
    };

Engine set up

This will set up and configure Planet

127
128
129
130
131
132
133
134
135
136
137
138
    template<typename F, typename... Args>
    inline int co_main(F f, planet::version const &version, Args... args) {
        felspar::io::poll_warden w;
        init sdl{w, version};
        ttf text{sdl};
        return w.run<int, init, F, Args...>(
                sdl, &init::run, std::forward<F>(f),
                std::forward<Args>(args)...);
    }


}