1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-24 00:03:11 +01:00

Refactor IPlatformEnvironment (#5590)

This commit is contained in:
Ted John
2017-06-11 12:53:37 +01:00
committed by GitHub
parent b563d26ffe
commit 0d8f9d6618
15 changed files with 184 additions and 146 deletions

View File

@@ -17,6 +17,7 @@
#include <openrct2/audio/AudioContext.h> #include <openrct2/audio/AudioContext.h>
#include <openrct2/Context.h> #include <openrct2/Context.h>
#include <openrct2/OpenRCT2.h> #include <openrct2/OpenRCT2.h>
#include <openrct2/PlatformEnvironment.h>
#include <openrct2/ui/UiContext.h> #include <openrct2/ui/UiContext.h>
#include "audio/AudioContext.h" #include "audio/AudioContext.h"
#include "Ui.h" #include "Ui.h"
@@ -49,9 +50,10 @@ int main(int argc, char * * argv)
else else
{ {
// Run OpenRCT2 with a UI context // Run OpenRCT2 with a UI context
auto env = CreatePlatformEnvironment();
auto audioContext = CreateAudioContext(); auto audioContext = CreateAudioContext();
auto uiContext = CreateUiContext(); auto uiContext = CreateUiContext(env);
auto context = CreateContext(audioContext, uiContext); auto context = CreateContext(env, audioContext, uiContext);
context->RunOpenRCT2(argc, argv); context->RunOpenRCT2(argc, argv);

View File

@@ -59,7 +59,8 @@ class UiContext final : public IUiContext
private: private:
constexpr static uint32 TOUCH_DOUBLE_TIMEOUT = 300; constexpr static uint32 TOUCH_DOUBLE_TIMEOUT = 300;
IPlatformUiContext * const _platformUiContext; IPlatformEnvironment * const _env;
IPlatformUiContext * const _platformUiContext;
CursorRepository _cursorRepository; CursorRepository _cursorRepository;
@@ -84,14 +85,18 @@ private:
float _gestureRadius = 0; float _gestureRadius = 0;
public: public:
UiContext() UiContext(IPlatformEnvironment * env)
: _platformUiContext(CreatePlatformUiContext()) : _env(env),
_platformUiContext(CreatePlatformUiContext())
{ {
if (SDL_Init(SDL_INIT_VIDEO) < 0) if (SDL_Init(SDL_INIT_VIDEO) < 0)
{ {
SDLException::Throw("SDL_Init(SDL_INIT_VIDEO)"); SDLException::Throw("SDL_Init(SDL_INIT_VIDEO)");
} }
_cursorRepository.LoadCursors(); _cursorRepository.LoadCursors();
// Temporary to prevent warning, will be used for keyboard shortcuts
UNUSED(_env);
} }
~UiContext() override ~UiContext() override
@@ -690,7 +695,7 @@ private:
} }
}; };
IUiContext * OpenRCT2::Ui::CreateUiContext() IUiContext * OpenRCT2::Ui::CreateUiContext(IPlatformEnvironment * env)
{ {
return new UiContext(); return new UiContext(env);
} }

View File

@@ -24,6 +24,7 @@ struct SDL_Window;
namespace OpenRCT2 namespace OpenRCT2
{ {
interface IContext; interface IContext;
interface IPlatformEnvironment;
namespace Ui namespace Ui
{ {
@@ -41,7 +42,7 @@ namespace OpenRCT2
virtual std::string ShowDirectoryDialog(SDL_Window * window, const std::string &title) abstract; virtual std::string ShowDirectoryDialog(SDL_Window * window, const std::string &title) abstract;
}; };
IUiContext * CreateUiContext(); IUiContext * CreateUiContext(IPlatformEnvironment * env);
IPlatformUiContext * CreatePlatformUiContext(); IPlatformUiContext * CreatePlatformUiContext();
} }
} }

View File

@@ -70,11 +70,11 @@ namespace OpenRCT2
constexpr static uint32 UPDATE_TIME_MS = 25; constexpr static uint32 UPDATE_TIME_MS = 25;
// Dependencies // Dependencies
IAudioContext * const _audioContext = nullptr; IPlatformEnvironment * const _env = nullptr;
IUiContext * const _uiContext = nullptr; IAudioContext * const _audioContext = nullptr;
IUiContext * const _uiContext = nullptr;
// Services // Services
IPlatformEnvironment * _env = nullptr;
IObjectRepository * _objectRepository = nullptr; IObjectRepository * _objectRepository = nullptr;
ITrackDesignRepository * _trackDesignRepository = nullptr; ITrackDesignRepository * _trackDesignRepository = nullptr;
IScenarioRepository * _scenarioRepository = nullptr; IScenarioRepository * _scenarioRepository = nullptr;
@@ -93,8 +93,9 @@ namespace OpenRCT2
static Context * Instance; static Context * Instance;
public: public:
Context(IAudioContext * audioContext, IUiContext * uiContext) Context(IPlatformEnvironment * env, IAudioContext * audioContext, IUiContext * uiContext)
: _audioContext(audioContext), : _env(env),
_audioContext(audioContext),
_uiContext(uiContext) _uiContext(uiContext)
{ {
Instance = this; Instance = this;
@@ -151,13 +152,6 @@ namespace OpenRCT2
crash_init(); crash_init();
// Sets up the environment OpenRCT2 is running in, e.g. directory paths
_env = SetupEnvironment();
if (_env == nullptr)
{
return false;
}
if (!rct2_interop_setup_segment()) if (!rct2_interop_setup_segment())
{ {
log_fatal("Unable to load RCT2 data sector"); log_fatal("Unable to load RCT2 data sector");
@@ -237,64 +231,6 @@ namespace OpenRCT2
} }
private: private:
IPlatformEnvironment * SetupEnvironment()
{
utf8 userPath[MAX_PATH];
platform_resolve_openrct_data_path();
platform_resolve_user_data_path();
platform_get_user_directory(userPath, NULL, sizeof(userPath));
if (!platform_ensure_directory_exists(userPath))
{
Console::Error::WriteLine("Could not create user directory (do you have write access to your documents folder?)");
return nullptr;
}
platform_get_exe_path(gExePath, sizeof(gExePath));
log_verbose("Setting exe path to %s", gExePath);
config_set_defaults();
if (!config_open_default())
{
if (!config_find_or_browse_install_directory())
{
gConfigGeneral.last_run_version = String::Duplicate(OPENRCT2_VERSION);
config_save_default();
utf8 path[MAX_PATH];
config_get_default_path(path, sizeof(path));
Console::Error::WriteLine("An RCT2 install directory must be specified! Please edit \"game_path\" in %s.", path);
return nullptr;
}
config_save_default();
}
if (!rct2_init_directories())
{
return nullptr;
}
if (!rct2_startup_checks())
{
return nullptr;
}
utf8 path[260];
std::string basePaths[4];
basePaths[(size_t)DIRBASE::RCT1] = String::ToStd(gConfigGeneral.rct1_path);
basePaths[(size_t)DIRBASE::RCT2] = String::ToStd(gConfigGeneral.rct2_path);
platform_get_openrct_data_path(path, sizeof(path));
basePaths[(size_t)DIRBASE::OPENRCT2] = std::string(path);
platform_get_user_directory(path, nullptr, sizeof(path));
basePaths[(size_t)DIRBASE::USER] = std::string(path);
IPlatformEnvironment * env = CreatePlatformEnvironment(basePaths);
// Log base paths
log_verbose("DIRBASE::RCT1 : %s", env->GetDirectoryPath(DIRBASE::RCT1).c_str());
log_verbose("DIRBASE::RCT2 : %s", env->GetDirectoryPath(DIRBASE::RCT2).c_str());
log_verbose("DIRBASE::OPENRCT2: %s", env->GetDirectoryPath(DIRBASE::OPENRCT2).c_str());
log_verbose("DIRBASE::USER : %s", env->GetDirectoryPath(DIRBASE::USER).c_str());
return env;
}
/** /**
* Launches the game, after command line arguments have been parsed and processed. * Launches the game, after command line arguments have been parsed and processed.
*/ */
@@ -564,18 +500,20 @@ namespace OpenRCT2
class PlainContext final : public Context class PlainContext final : public Context
{ {
std::unique_ptr<IAudioContext> _audioContext; std::unique_ptr<IPlatformEnvironment> _env;
std::unique_ptr<IUiContext> _uiContext; std::unique_ptr<IAudioContext> _audioContext;
std::unique_ptr<IUiContext> _uiContext;
public: public:
PlainContext() PlainContext()
: PlainContext(CreateDummyAudioContext(), CreateDummyUiContext()) : PlainContext(CreatePlatformEnvironment(), CreateDummyAudioContext(), CreateDummyUiContext())
{ {
} }
PlainContext(IAudioContext * audioContext, IUiContext * uiContext) PlainContext(IPlatformEnvironment * env, IAudioContext * audioContext, IUiContext * uiContext)
: Context(audioContext, uiContext) : Context(env, audioContext, uiContext)
{ {
_env = std::unique_ptr<IPlatformEnvironment>(env);
_audioContext = std::unique_ptr<IAudioContext>(audioContext); _audioContext = std::unique_ptr<IAudioContext>(audioContext);
_uiContext = std::unique_ptr<IUiContext>(uiContext); _uiContext = std::unique_ptr<IUiContext>(uiContext);
} }
@@ -588,9 +526,9 @@ namespace OpenRCT2
return new PlainContext(); return new PlainContext();
} }
IContext * CreateContext(Audio::IAudioContext * audioContext, IUiContext * uiContext) IContext * CreateContext(IPlatformEnvironment * env, Audio::IAudioContext * audioContext, IUiContext * uiContext)
{ {
return new Context(audioContext, uiContext); return new Context(env, audioContext, uiContext);
} }
IContext * GetContext() IContext * GetContext()

View File

@@ -59,6 +59,8 @@ enum
namespace OpenRCT2 namespace OpenRCT2
{ {
interface IPlatformEnvironment;
namespace Audio namespace Audio
{ {
interface IAudioContext; interface IAudioContext;
@@ -86,7 +88,7 @@ namespace OpenRCT2
}; };
IContext * CreateContext(); IContext * CreateContext();
IContext * CreateContext(Audio::IAudioContext * audioContext, Ui::IUiContext * uiContext); IContext * CreateContext(IPlatformEnvironment * env, Audio::IAudioContext * audioContext, Ui::IUiContext * uiContext);
IContext * GetContext(); IContext * GetContext();
} }

View File

@@ -14,17 +14,24 @@
*****************************************************************************/ *****************************************************************************/
#pragma endregion #pragma endregion
#include "config/Config.h"
#include "core/Console.hpp"
#include "core/Exception.hpp" #include "core/Exception.hpp"
#include "core/Guard.hpp" #include "core/Guard.hpp"
#include "core/Path.hpp" #include "core/Path.hpp"
#include "core/String.hpp" #include "core/String.hpp"
#include "OpenRCT2.h"
#include "PlatformEnvironment.h" #include "PlatformEnvironment.h"
#include "Version.h"
extern "C" extern "C"
{ {
#include "platform/platform.h" #include "platform/platform.h"
#include "rct2.h"
} }
using namespace OpenRCT2;
class PlatformEnvironment final : public IPlatformEnvironment class PlatformEnvironment final : public IPlatformEnvironment
{ {
private: private:
@@ -84,11 +91,69 @@ private:
static const char * FileNames[]; static const char * FileNames[];
}; };
IPlatformEnvironment * CreatePlatformEnvironment(DIRBASE_VALUES basePaths) IPlatformEnvironment * OpenRCT2::CreatePlatformEnvironment(DIRBASE_VALUES basePaths)
{ {
return new PlatformEnvironment(basePaths); return new PlatformEnvironment(basePaths);
} }
IPlatformEnvironment * OpenRCT2::CreatePlatformEnvironment()
{
utf8 userPath[MAX_PATH];
platform_resolve_openrct_data_path();
platform_resolve_user_data_path();
platform_get_user_directory(userPath, NULL, sizeof(userPath));
if (!platform_ensure_directory_exists(userPath))
{
Console::Error::WriteLine("Could not create user directory (do you have write access to your documents folder?)");
return nullptr;
}
platform_get_exe_path(gExePath, sizeof(gExePath));
log_verbose("Setting exe path to %s", gExePath);
config_set_defaults();
if (!config_open_default())
{
if (!config_find_or_browse_install_directory())
{
gConfigGeneral.last_run_version = String::Duplicate(OPENRCT2_VERSION);
config_save_default();
utf8 path[MAX_PATH];
config_get_default_path(path, sizeof(path));
Console::Error::WriteLine("An RCT2 install directory must be specified! Please edit \"game_path\" in %s.", path);
return nullptr;
}
config_save_default();
}
if (!rct2_init_directories())
{
return nullptr;
}
if (!rct2_startup_checks())
{
return nullptr;
}
utf8 path[260];
std::string basePaths[4];
basePaths[(size_t)DIRBASE::RCT1] = String::ToStd(gConfigGeneral.rct1_path);
basePaths[(size_t)DIRBASE::RCT2] = String::ToStd(gConfigGeneral.rct2_path);
platform_get_openrct_data_path(path, sizeof(path));
basePaths[(size_t)DIRBASE::OPENRCT2] = std::string(path);
platform_get_user_directory(path, nullptr, sizeof(path));
basePaths[(size_t)DIRBASE::USER] = std::string(path);
IPlatformEnvironment * env = OpenRCT2::CreatePlatformEnvironment(basePaths);
// Log base paths
log_verbose("DIRBASE::RCT1 : %s", env->GetDirectoryPath(DIRBASE::RCT1).c_str());
log_verbose("DIRBASE::RCT2 : %s", env->GetDirectoryPath(DIRBASE::RCT2).c_str());
log_verbose("DIRBASE::OPENRCT2: %s", env->GetDirectoryPath(DIRBASE::OPENRCT2).c_str());
log_verbose("DIRBASE::USER : %s", env->GetDirectoryPath(DIRBASE::USER).c_str());
return env;
}
const char * PlatformEnvironment::DirectoryNamesRCT2[] = const char * PlatformEnvironment::DirectoryNamesRCT2[] =
{ {
"Data", // DATA "Data", // DATA

View File

@@ -19,58 +19,62 @@
#include <string> #include <string>
#include "common.h" #include "common.h"
enum class DIRBASE : sint32 namespace OpenRCT2
{ {
RCT1, // Base directory for original RollerCoaster Tycoon 1 content. enum class DIRBASE : sint32
RCT2, // Base directory for original RollerCoaster Tycoon 2 content. {
OPENRCT2, // Base directory for OpenRCT2 installation. RCT1, // Base directory for original RollerCoaster Tycoon 1 content.
USER, // Base directory for OpenRCT2 user content. RCT2, // Base directory for original RollerCoaster Tycoon 2 content.
}; OPENRCT2, // Base directory for OpenRCT2 installation.
constexpr sint32 DIRBASE_COUNT = 4; USER, // Base directory for OpenRCT2 user content.
using DIRBASE_VALUES = std::string[DIRBASE_COUNT]; };
constexpr sint32 DIRBASE_COUNT = 4;
using DIRBASE_VALUES = std::string[DIRBASE_COUNT];
enum class DIRID enum class DIRID
{ {
DATA, // Contains g1.dat, music etc. DATA, // Contains g1.dat, music etc.
LANDSCAPE, // Contains scenario editor landscapes (SC6). LANDSCAPE, // Contains scenario editor landscapes (SC6).
LANGUAGE, // Contains language packs. LANGUAGE, // Contains language packs.
LOG_CHAT, // Contains chat logs. LOG_CHAT, // Contains chat logs.
LOG_SERVER, // Contains server logs. LOG_SERVER, // Contains server logs.
NETWORK_KEY, // Contains the user's public and private keys. NETWORK_KEY, // Contains the user's public and private keys.
OBJECT, // Contains objects. OBJECT, // Contains objects.
SAVE, // Contains saved games (SV6). SAVE, // Contains saved games (SV6).
SCENARIO, // Contains scenarios (SC6). SCENARIO, // Contains scenarios (SC6).
SCREENSHOT, // Contains screenshots. SCREENSHOT, // Contains screenshots.
SEQUENCE, // Contains title sequences. SEQUENCE, // Contains title sequences.
SHADER, // Contains OpenGL shaders. SHADER, // Contains OpenGL shaders.
THEME, // Contains interface themes. THEME, // Contains interface themes.
TRACK, // Contains track designs. TRACK, // Contains track designs.
}; };
enum class PATHID enum class PATHID
{ {
CONFIG, // Main configuration (config.ini). CONFIG, // Main configuration (config.ini).
CONFIG_KEYBOARD, // Keyboard shortcuts. (hotkeys.cfg) CONFIG_KEYBOARD, // Keyboard shortcuts. (hotkeys.cfg)
CACHE_OBJECTS, // Object repository cache (objects.idx). CACHE_OBJECTS, // Object repository cache (objects.idx).
CACHE_TRACKS, // Track repository cache (tracks.idx). CACHE_TRACKS, // Track repository cache (tracks.idx).
NETWORK_GROUPS, // Server groups with permissions (groups.json). NETWORK_GROUPS, // Server groups with permissions (groups.json).
NETWORK_SERVERS, // Saved servers (servers.cfg). NETWORK_SERVERS, // Saved servers (servers.cfg).
NETWORK_USERS, // Users and their groups (users.json). NETWORK_USERS, // Users and their groups (users.json).
SCORES, // Scenario scores (highscores.dat). SCORES, // Scenario scores (highscores.dat).
SCORES_LEGACY, // Scenario scores, legacy (scores.dat). SCORES_LEGACY, // Scenario scores, legacy (scores.dat).
SCORES_RCT2, // Scenario scores, rct2 (\Saved Games\scores.dat). SCORES_RCT2, // Scenario scores, rct2 (\Saved Games\scores.dat).
}; };
/** /**
* Interface for retrieving paths and other environment related things. * Interface for retrieving paths and other environment related things.
*/ */
interface IPlatformEnvironment interface IPlatformEnvironment
{ {
virtual ~IPlatformEnvironment() = default; virtual ~IPlatformEnvironment() = default;
virtual std::string GetDirectoryPath(DIRBASE base) const abstract; virtual std::string GetDirectoryPath(DIRBASE base) const abstract;
virtual std::string GetDirectoryPath(DIRBASE base, DIRID did) const abstract; virtual std::string GetDirectoryPath(DIRBASE base, DIRID did) const abstract;
virtual std::string GetFilePath(PATHID pathid) const abstract; virtual std::string GetFilePath(PATHID pathid) const abstract;
}; };
IPlatformEnvironment * CreatePlatformEnvironment(DIRBASE_VALUES basePaths); IPlatformEnvironment * CreatePlatformEnvironment(DIRBASE_VALUES basePaths);
IPlatformEnvironment * CreatePlatformEnvironment();
}

View File

@@ -74,6 +74,8 @@ extern "C" {
#pragma comment(lib, "Ws2_32.lib") #pragma comment(lib, "Ws2_32.lib")
using namespace OpenRCT2;
Network gNetwork; Network gNetwork;
enum { enum {

View File

@@ -85,15 +85,19 @@ enum {
NETWORK_TICK_FLAG_CHECKSUMS = 1 << 0, NETWORK_TICK_FLAG_CHECKSUMS = 1 << 0,
}; };
interface IPlatformEnvironment; struct ObjectRepositoryItem;
struct ObjectRepositoryItem;
namespace OpenRCT2
{
interface IPlatformEnvironment;
}
class Network class Network
{ {
public: public:
Network(); Network();
~Network(); ~Network();
void SetEnvironment(IPlatformEnvironment * env); void SetEnvironment(OpenRCT2::IPlatformEnvironment * env);
bool Init(); bool Init();
void Close(); void Close();
bool BeginClient(const char* host, uint16 port); bool BeginClient(const char* host, uint16 port);
@@ -231,7 +235,7 @@ private:
std::string _chatLogFilenameFormat = "%Y%m%d-%H%M%S.txt"; std::string _chatLogFilenameFormat = "%Y%m%d-%H%M%S.txt";
std::string _serverLogPath; std::string _serverLogPath;
std::string _serverLogFilenameFormat = "-%Y%m%d-%H%M%S.txt"; std::string _serverLogFilenameFormat = "-%Y%m%d-%H%M%S.txt";
IPlatformEnvironment * _env; OpenRCT2::IPlatformEnvironment * _env;
void UpdateServer(); void UpdateServer();
void UpdateClient(); void UpdateClient();

View File

@@ -53,6 +53,8 @@ extern "C"
#include "../util/util.h" #include "../util/util.h"
} }
using namespace OpenRCT2;
constexpr uint16 OBJECT_REPOSITORY_VERSION = 10; constexpr uint16 OBJECT_REPOSITORY_VERSION = 10;
#pragma pack(push, 1) #pragma pack(push, 1)

View File

@@ -32,9 +32,12 @@ extern "C"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
interface IPlatformEnvironment;
interface IStream; interface IStream;
class Object; class Object;
namespace OpenRCT2
{
interface IPlatformEnvironment;
}
#else #else
typedef struct Object Object; typedef struct Object Object;
#endif #endif
@@ -87,7 +90,7 @@ interface IObjectRepository
virtual void WritePackedObjects(IStream * stream, std::vector<const ObjectRepositoryItem *> &objects) abstract; virtual void WritePackedObjects(IStream * stream, std::vector<const ObjectRepositoryItem *> &objects) abstract;
}; };
IObjectRepository * CreateObjectRepository(IPlatformEnvironment * env); IObjectRepository * CreateObjectRepository(OpenRCT2::IPlatformEnvironment * env);
IObjectRepository * GetObjectRepository(); IObjectRepository * GetObjectRepository();
bool IsObjectCustom(const ObjectRepositoryItem * object); bool IsObjectCustom(const ObjectRepositoryItem * object);

View File

@@ -36,6 +36,8 @@ extern "C"
#include "track_design.h" #include "track_design.h"
} }
using namespace OpenRCT2;
#pragma pack(push, 1) #pragma pack(push, 1)
struct TrackRepositoryHeader struct TrackRepositoryHeader
{ {

View File

@@ -28,7 +28,10 @@ typedef struct track_design_file_ref
#include <string> #include <string>
interface IPlatformEnvironment; namespace OpenRCT2
{
interface IPlatformEnvironment;
}
interface ITrackDesignRepository interface ITrackDesignRepository
{ {
@@ -46,7 +49,7 @@ interface ITrackDesignRepository
virtual std::string Install(const std::string &path) abstract; virtual std::string Install(const std::string &path) abstract;
}; };
ITrackDesignRepository * CreateTrackDesignRepository(IPlatformEnvironment * env); ITrackDesignRepository * CreateTrackDesignRepository(OpenRCT2::IPlatformEnvironment * env);
ITrackDesignRepository * GetTrackDesignRepository(); ITrackDesignRepository * GetTrackDesignRepository();
#endif #endif

View File

@@ -39,6 +39,8 @@ extern "C"
#include "scenario.h" #include "scenario.h"
} }
using namespace OpenRCT2;
static sint32 ScenarioCategoryCompare(sint32 categoryA, sint32 categoryB) static sint32 ScenarioCategoryCompare(sint32 categoryA, sint32 categoryB)
{ {
if (categoryA == categoryB) return 0; if (categoryA == categoryB) return 0;

View File

@@ -56,7 +56,10 @@ typedef struct scenario_index_entry
#ifdef __cplusplus #ifdef __cplusplus
interface IPlatformEnvironment; namespace OpenRCT2
{
interface IPlatformEnvironment;
}
interface IScenarioRepository interface IScenarioRepository
{ {
@@ -75,7 +78,7 @@ interface IScenarioRepository
virtual bool TryRecordHighscore(const utf8 * scenarioFileName, money32 companyValue, const utf8 * name) abstract; virtual bool TryRecordHighscore(const utf8 * scenarioFileName, money32 companyValue, const utf8 * name) abstract;
}; };
IScenarioRepository * CreateScenarioRepository(IPlatformEnvironment * env); IScenarioRepository * CreateScenarioRepository(OpenRCT2::IPlatformEnvironment * env);
IScenarioRepository * GetScenarioRepository(); IScenarioRepository * GetScenarioRepository();
#endif #endif