Skip to content

Commit

Permalink
[kernel] chore: overhaul how configuration is initialized
Browse files Browse the repository at this point in the history
  • Loading branch information
jd28 committed Dec 13, 2023
1 parent 231dc99 commit 116f86a
Show file tree
Hide file tree
Showing 20 changed files with 193 additions and 180 deletions.
16 changes: 3 additions & 13 deletions benchmarks/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,21 +319,11 @@ int main(int argc, char** argv)

nw::init_logger(argc, argv);

if (probe) {
auto info = nw::probe_nwn_install();
nwk::config().initialize({
info.version,
info.install,
info.user,
});
} else {
nwk::config().initialize({
nw::GameVersion::vEE,
"test_data/root/",
"test_data/user/",
});
if (!probe) {
nwk::config().set_paths("test_data/root/", "test_data/user/");
}

nwk::config().initialize();
nwk::services().start();
nwk::load_profile(new nwn1::Profile);

Expand Down
1 change: 1 addition & 0 deletions docs/fake/rollnw/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class GameVersion(enum.Enum):
"""Game versions"""
v1_69 = auto()
vEE = auto()
nwn2 = auto()


class PathAlias(enum.Enum):
Expand Down
37 changes: 26 additions & 11 deletions docs/fake/rollnw/kernel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,30 @@
class ConfigOptions:
"""Configuration options
Args:
probe (bool): If true, probe for an NWN install. (Default True)
version (GameVersion): NWN version install to probe for. (Default GameVersion.vEE)
Attributes:
version (GameVersion): Game version
install (str): NWN root install directory
user (str): NWN user directory
include_install (bool): If true, load base game data. (Default True)
include_nwsync (bool): If true, load NWSync data. (Default True)
include_user (bool): If true, load user data. (Default True)
"""

def __init__(self, probe: bool = True, version: GameVersion = GameVersion.vEE):
pass

pass

class Config:
"""Configuration service
"""

def alias_path(self, alias: PathAlias) -> str:
"""Gets alias path"""
return ""

def initialize(self, options: ConfigOptions):
"""Initialize config system"""
pass

def install_path(self) -> str:
"""Gets game install path"""
return ""

def nwn_ini(self) -> Ini:
"""Gets parsed nwn.ini
"""
Expand All @@ -55,11 +55,26 @@ def resolve_alias(self, alias_path: str) -> str:
"""Resolves alias path"""
pass

def user_path(self) -> str:
"""Gets game install path"""
return ""

def userpatch_ini(self) -> Ini:
"""Gets parsed userpatch.ini
"""
pass

def set_paths(self, install: str, user: str):
"""Sets game paths
Note: Must be called before ``initialize``
"""

def set_version(self, version: GameVersion):
"""Sets game paths
Note: Must be called before ``initialize``
"""

class EffectSystemStats:
"""Effect system stat data
Expand Down Expand Up @@ -264,7 +279,7 @@ def rules():
pass


def start(config=None):
def start(options: Optional[ConfigOptions]):
"""Starts kernel services
Args:
Expand Down
12 changes: 6 additions & 6 deletions docs/gs/using.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ While the library is far from done, basic usage would be as follows.
// Initialize logger
nw::init_logger(argc, argv);
// Say this application is specific to 1.69.
// This must be set before the initialize call below. The default is NWN:EE, so in that case,
// ``set_version`` need not be called
nw::kernel::config().set_version(GameVersion::v1_69);
// Sets config for the system, paths, version, etc.
auto info = nw::probe_nwn_install();
nw::kernel::config().initialize({
info.version,
info.install,
info.user,
});
nw::kernel::config().initialize();
// Initializes all systems
nw::kernel::services().start();
Expand Down
2 changes: 1 addition & 1 deletion docs/structure/kernel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ aliases, Ini and Toml settings.

.. code:: cpp
if (config.options().version == nw::GameVersion::vEE) {
if (nw::kernel::config().version() == nw::GameVersion::vEE) {
REQUIRE_FALSE(config.settings_tml().empty());
REQUIRE(*config.settings_tml()["game"]["gore"].as<int64_t>() == 1);
}
Expand Down
57 changes: 44 additions & 13 deletions lib/nw/kernel/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,39 +95,49 @@ fs::path Config::alias_path(PathAlias alias)
void Config::initialize(ConfigOptions options)
{
options_ = std::move(options);
LOG_F(INFO, "kernel: initializing config system");

if (options_.version == GameVersion::invalid) {
LOG_F(ERROR, "Failed to find valid NWN(:EE) install.");
return;
if (install_.empty()) {
auto info = probe_nwn_install(version_);
install_ = info.install;
LOG_F(INFO, "install: {}", install_);
if (user_.empty()) { user_ = info.user; }
}
LOG_F(INFO, "kernel: initializing config system");

// [TODO] Find a better method of conveying this error
CHECK_F(!install_.empty(), "Failed to find valid NWN install.");

if (options_.version == GameVersion::vEE) {
auto path = options_.user / "nwn.ini";
if (version_ == GameVersion::vEE) {
auto path = user_ / "nwn.ini";
if (fs::exists(path)) { nwn_ini_ = Ini{path}; }

path = options_.user / "nwnplayer.ini";
path = user_ / "nwnplayer.ini";
if (fs::exists(path)) { nwnplayer_ini_ = Ini{path}; }

path = options_.user / "userpatch.ini";
path = user_ / "userpatch.ini";
if (fs::exists(path)) { userpatch_ini_ = Ini{path}; }

path = options_.user / "settings.tml";
path = user_ / "settings.tml";
if (fs::exists(path)) {
settings_tml_ = toml::parse_file(path_to_string(path));
}
} else if (options_.version == GameVersion::v1_69) {
auto path = options_.user / "nwn.ini";
} else if (version_ == GameVersion::v1_69) {
auto path = user_ / "nwn.ini";
if (fs::exists(path)) { nwn_ini_ = Ini{path}; }

path = options_.user / "nwnplayer.ini";
path = user_ / "nwnplayer.ini";
if (fs::exists(path)) { nwnplayer_ini_ = Ini{path}; }

path = options_.user / "nwnpatch.ini";
path = user_ / "nwnpatch.ini";
if (fs::exists(path)) { userpatch_ini_ = Ini{path}; }
}
}

const std::filesystem::path& Config::install_path() const noexcept
{
return install_;
}

const ConfigOptions& Config::options() const noexcept
{
return options_;
Expand Down Expand Up @@ -227,14 +237,35 @@ fs::path Config::resolve_alias(std::string_view alias_path) const
return {};
}

void Config::set_paths(const std::filesystem::path install, const std::filesystem::path user)
{
install_ = std::move(install);
user_ = std::move(user);
}

void Config::set_version(GameVersion version)
{
version_ = version;
}

const toml::table& Config::settings_tml() const noexcept
{
return settings_tml_;
}

const std::filesystem::path& Config::user_path() const noexcept
{
return user_;
}

const Ini& Config::userpatch_ini() const noexcept
{
return userpatch_ini_;
}

GameVersion Config::version() const noexcept
{
return version_;
}

} // namespace nw::kernel
31 changes: 24 additions & 7 deletions lib/nw/kernel/Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@ namespace nw {

/// Configuration options, maybe there will be an actual config file.. someday.
struct ConfigOptions {
GameVersion version; ///< Game version
std::filesystem::path install; ///< Path to Game installation directory
std::filesystem::path user; ///< Path to User directory
bool include_install = true; ///< Load Game install files
bool include_nwsync = true; ///< Load NWSync files
bool include_user = true; ///< Load User files, note: if false, value overrides ``include_nwsync``
bool include_install = true; ///< Load Game install files
bool include_nwsync = true; ///< Load NWSync files
bool include_user = true; ///< Load User files, note: if false, value overrides ``include_nwsync``
};

namespace kernel {
Expand All @@ -25,7 +22,10 @@ struct Config {
std::filesystem::path alias_path(PathAlias alias);

/// Initializes configuration system
void initialize(ConfigOptions options);
void initialize(ConfigOptions options = {});

/// Game installation path
const std::filesystem::path& install_path() const noexcept;

/// Gets nwn.ini
const Ini& nwn_ini() const noexcept;
Expand All @@ -39,14 +39,31 @@ struct Config {
/// Resolves a path alias
std::filesystem::path resolve_alias(std::string_view alias_path) const;

/// Sets game paths.
/// @note If paths are unset, the kernel will attempt to find them.
void set_paths(const std::filesystem::path install, const std::filesystem::path user);

/// Sets game version
void set_version(GameVersion version);

/// Gets settings.tml
/// @note Return value will be `empty` if 1.69
const toml::table& settings_tml() const noexcept;

/// Path to user directory
const std::filesystem::path& user_path() const noexcept;

/// Gets userpatch.ini or nwnpatch.ini if 1.69
const Ini& userpatch_ini() const noexcept;

/// Gets games version
GameVersion version() const noexcept;

private:
GameVersion version_ = GameVersion::vEE; ///< Game version
std::filesystem::path install_; ///< Path to Game installation directory
std::filesystem::path user_; ///< Path to User directory

ConfigOptions options_;
Ini nwn_ini_;
Ini nwnplayer_ini_;
Expand Down
58 changes: 29 additions & 29 deletions lib/nw/kernel/Resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ Resources::Resources(const Resources* parent)
void Resources::initialize()
{
LOG_F(INFO, "kernel: initializing resource system");
LOG_F(INFO, "kernel: root directory: {}", config().options().install);
LOG_F(INFO, "kernel: user directory: {}", config().options().user);
LOG_F(INFO, "kernel: root directory: {}", config().install_path());
LOG_F(INFO, "kernel: user directory: {}", config().user_path());

if (config().options().include_user) {
ambient_user_ = Directory{config().alias_path(PathAlias::ambient)};
Expand All @@ -63,7 +63,7 @@ void Resources::initialize()
}

if (config().options().include_user) {
if (config().options().version == GameVersion::vEE) {
if (config().version() == GameVersion::vEE) {
if (config().options().include_nwsync) {
nwsync_ = NWSync{config().alias_path(PathAlias::nwsync)};
}
Expand All @@ -86,41 +86,41 @@ void Resources::initialize()

if (config().options().include_install) {
texture_packs_.reserve(4);
if (config().options().version == GameVersion::vEE) {
ambient_install_ = Directory{config().options().install / "data/amb/"};
dmvault_install_ = Directory{config().options().install / "data/dmv/"};
localvault_install_ = Directory{config().options().install / "data/lcv/"};
music_install_ = Directory{config().options().install / "data/mus"};
override_install_ = Directory{config().options().install / "ovr"};
portraits_install_ = Directory{config().options().install / "data/prt/"};

texture_packs_.emplace_back(config().options().install / "data/txpk/xp2_tex_tpa.erf");
texture_packs_.emplace_back(config().options().install / "data/txpk/xp1_tex_tpa.erf");
texture_packs_.emplace_back(config().options().install / "data/txpk/textures_tpa.erf");
texture_packs_.emplace_back(config().options().install / "data/txpk/tiles_tpa.erf");
if (config().version() == GameVersion::vEE) {
ambient_install_ = Directory{config().install_path() / "data/amb/"};
dmvault_install_ = Directory{config().install_path() / "data/dmv/"};
localvault_install_ = Directory{config().install_path() / "data/lcv/"};
music_install_ = Directory{config().install_path() / "data/mus"};
override_install_ = Directory{config().install_path() / "ovr"};
portraits_install_ = Directory{config().install_path() / "data/prt/"};

texture_packs_.emplace_back(config().install_path() / "data/txpk/xp2_tex_tpa.erf");
texture_packs_.emplace_back(config().install_path() / "data/txpk/xp1_tex_tpa.erf");
texture_packs_.emplace_back(config().install_path() / "data/txpk/textures_tpa.erf");
texture_packs_.emplace_back(config().install_path() / "data/txpk/tiles_tpa.erf");

keys_.reserve(2);
auto lang = strings().global_language();
if (lang != LanguageID::english) {
auto shortcode = Language::to_string(lang);
keys_.emplace_back(config().options().install / "lang" / shortcode / "data" / "nwn_base_loc.key");
keys_.emplace_back(config().install_path() / "lang" / shortcode / "data" / "nwn_base_loc.key");
}
keys_.emplace_back(config().options().install / "data/nwn_base.key");
keys_.emplace_back(config().install_path() / "data/nwn_base.key");
} else {
texture_packs_.emplace_back(config().options().install / "texturepacks/xp2_tex_tpa.erf");
texture_packs_.emplace_back(config().options().install / "texturepacks/xp1_tex_tpa.erf");
texture_packs_.emplace_back(config().options().install / "texturepacks/textures_tpa.erf");
texture_packs_.emplace_back(config().options().install / "texturepacks/tiles_tpa.erf");
texture_packs_.emplace_back(config().install_path() / "texturepacks/xp2_tex_tpa.erf");
texture_packs_.emplace_back(config().install_path() / "texturepacks/xp1_tex_tpa.erf");
texture_packs_.emplace_back(config().install_path() / "texturepacks/textures_tpa.erf");
texture_packs_.emplace_back(config().install_path() / "texturepacks/tiles_tpa.erf");

keys_.reserve(8);
keys_.emplace_back(config().options().install / "xp3patch.key");
keys_.emplace_back(config().options().install / "xp3.key");
keys_.emplace_back(config().options().install / "xp2patch.key");
keys_.emplace_back(config().options().install / "xp2.key");
keys_.emplace_back(config().options().install / "xp1patch.key");
keys_.emplace_back(config().options().install / "xp1.key");
keys_.emplace_back(config().options().install / "patch.key");
keys_.emplace_back(config().options().install / "chitin.key");
keys_.emplace_back(config().install_path() / "xp3patch.key");
keys_.emplace_back(config().install_path() / "xp3.key");
keys_.emplace_back(config().install_path() / "xp2patch.key");
keys_.emplace_back(config().install_path() / "xp2.key");
keys_.emplace_back(config().install_path() / "xp1patch.key");
keys_.emplace_back(config().install_path() / "xp1.key");
keys_.emplace_back(config().install_path() / "patch.key");
keys_.emplace_back(config().install_path() / "chitin.key");
}
}
update_container_search();
Expand Down
2 changes: 1 addition & 1 deletion lib/nw/kernel/Strings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ InternedString Strings::get_interned(std::string_view str) const
void Strings::initialize()
{
auto lang = Language::to_string(global_language());
auto path = config().options().install / "lang" / lang / "data" / "dialog.tlk";
auto path = config().install_path() / "lang" / lang / "data" / "dialog.tlk";
load_dialog_tlk(path);
}

Expand Down
Loading

0 comments on commit 116f86a

Please sign in to comment.