init.hpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#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 <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.

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

Creation

31
32
        configuration(std::string_view appname);
        ~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.

51
        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.

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

Configuration file name

62
        std::filesystem::path config_filename;

Save game folder

64
        std::filesystem::path save_folder;

Logging

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

User's configuration

73
74
75
76
        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

80
81
82
83
        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

87
88
89
90
91
        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

95
96
    class init final {
      public:

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

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
        init(felspar::io::warden &w, std::string_view appname);
        ~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

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


}