Allow irrlicht to use an existing file system (instead of creating

a new each time a device is created). This simplifies the implementation
of the file manager (now the file manager always exists, even when
deleting the dummy device and creating the real device).
This commit is contained in:
hiker 2015-01-06 07:48:32 +11:00
parent 32366015b7
commit 93a3e6c3da
8 changed files with 68 additions and 51 deletions

View File

@ -13,6 +13,7 @@
namespace irr namespace irr
{ {
class IEventReceiver; class IEventReceiver;
namespace io{ class IFileSystem; }
//! Structure for holding Irrlicht Device creation parameters. //! Structure for holding Irrlicht Device creation parameters.
/** This structure is used in the createDeviceEx() function. */ /** This structure is used in the createDeviceEx() function. */
@ -35,7 +36,8 @@ namespace irr
IgnoreInput(false), IgnoreInput(false),
Stereobuffer(false), Stereobuffer(false),
HighPrecisionFPU(false), HighPrecisionFPU(false),
EventReceiver(0), EventReceiver(NULL),
FileSystem(NULL),
WindowId(0), WindowId(0),
#ifdef _DEBUG #ifdef _DEBUG
LoggingLevel(ELL_DEBUG), LoggingLevel(ELL_DEBUG),
@ -71,6 +73,7 @@ namespace irr
Stereobuffer = other.Stereobuffer; Stereobuffer = other.Stereobuffer;
HighPrecisionFPU = other.HighPrecisionFPU; HighPrecisionFPU = other.HighPrecisionFPU;
EventReceiver = other.EventReceiver; EventReceiver = other.EventReceiver;
FileSystem = other.FileSystem;
WindowId = other.WindowId; WindowId = other.WindowId;
LoggingLevel = other.LoggingLevel; LoggingLevel = other.LoggingLevel;
DriverMultithreaded = other.DriverMultithreaded; DriverMultithreaded = other.DriverMultithreaded;
@ -205,6 +208,9 @@ namespace irr
//! A user created event receiver. //! A user created event receiver.
IEventReceiver* EventReceiver; IEventReceiver* EventReceiver;
//! A pointer to an existing file system to be used.
io::IFileSystem *FileSystem;
//! Window Id. //! Window Id.
/** If this is set to a value other than 0, the Irrlicht Engine /** If this is set to a value other than 0, the Irrlicht Engine
will be created in an already existing window. For windows, set will be created in an already existing window. For windows, set

View File

@ -329,7 +329,8 @@ namespace irr
bool fullscreen = false, bool fullscreen = false,
bool stencilbuffer = false, bool stencilbuffer = false,
bool vsync = false, bool vsync = false,
IEventReceiver* receiver = 0); IEventReceiver* receiver = 0,
io::IFileSystem *file_system = NULL);
//! typedef for Function Pointer //! typedef for Function Pointer
typedef IrrlichtDevice* (IRRCALLCONV *funcptr_createDevice )( typedef IrrlichtDevice* (IRRCALLCONV *funcptr_createDevice )(

View File

@ -40,8 +40,15 @@ CIrrDeviceStub::CIrrDeviceStub(const SIrrlichtCreationParameters& params)
os::Printer::Logger = Logger; os::Printer::Logger = Logger;
Randomizer = createDefaultRandomizer(); Randomizer = createDefaultRandomizer();
FileSystem = io::createFileSystem(); // If the user supplies a file system, use it instead of creating a new one
core::stringc s = "Irrlicht Engine version "; if (params.FileSystem)
{
FileSystem = params.FileSystem;
FileSystem->grab();
}
else
FileSystem = io::createFileSystem();
core::stringc s = "Irrlicht Engine version ";
s.append(getVersion()); s.append(getVersion());
os::Printer::log(s.c_str(), ELL_INFORMATION); os::Printer::log(s.c_str(), ELL_INFORMATION);

View File

@ -48,7 +48,8 @@ namespace irr
IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDevice(video::E_DRIVER_TYPE driverType, IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDevice(video::E_DRIVER_TYPE driverType,
const core::dimension2d<u32>& windowSize, const core::dimension2d<u32>& windowSize,
u32 bits, bool fullscreen, u32 bits, bool fullscreen,
bool stencilbuffer, bool vsync, IEventReceiver* res) bool stencilbuffer, bool vsync, IEventReceiver* res,
io::IFileSystem *file_system)
{ {
SIrrlichtCreationParameters p; SIrrlichtCreationParameters p;
p.DriverType = driverType; p.DriverType = driverType;
@ -58,6 +59,7 @@ namespace irr
p.Stencilbuffer = stencilbuffer; p.Stencilbuffer = stencilbuffer;
p.Vsync = vsync; p.Vsync = vsync;
p.EventReceiver = res; p.EventReceiver = res;
p.FileSystem = file_system;
return createDeviceEx(p); return createDeviceEx(p);
} }

View File

@ -109,8 +109,14 @@ IrrDriver::IrrDriver()
{ {
m_resolution_changing = RES_CHANGE_NONE; m_resolution_changing = RES_CHANGE_NONE;
m_phase = SOLID_NORMAL_AND_DEPTH_PASS; m_phase = SOLID_NORMAL_AND_DEPTH_PASS;
m_device = createDevice(video::EDT_NULL); m_device = createDevice(video::EDT_NULL,
m_request_screenshot = false; irr::core::dimension2d<u32>(640, 480),
/*bits*/16U, /**fullscreen*/ false,
/*stencilBuffer*/ false,
/*vsync*/false,
/*event receiver*/ NULL,
file_manager->getFileSystem());
m_request_screenshot = false;
m_shaders = NULL; m_shaders = NULL;
m_rtts = NULL; m_rtts = NULL;
m_post_processing = NULL; m_post_processing = NULL;
@ -390,8 +396,6 @@ void IrrDriver::initDevice()
// the problem for now. // the problem for now.
m_device->clearSystemMessages(); m_device->clearSystemMessages();
m_device->run(); m_device->run();
// Clear the pointer stored in the file manager
file_manager->dropFileSystem();
m_device->drop(); m_device->drop();
m_device = NULL; m_device = NULL;
@ -410,6 +414,7 @@ void IrrDriver::initDevice()
params.EventReceiver = this; params.EventReceiver = this;
params.Fullscreen = UserConfigParams::m_fullscreen; params.Fullscreen = UserConfigParams::m_fullscreen;
params.Vsync = UserConfigParams::m_vsync; params.Vsync = UserConfigParams::m_vsync;
params.FileSystem = file_manager->getFileSystem();
params.WindowSize = params.WindowSize =
core::dimension2du(UserConfigParams::m_width, core::dimension2du(UserConfigParams::m_width,
UserConfigParams::m_height); UserConfigParams::m_height);
@ -456,7 +461,8 @@ void IrrDriver::initDevice()
UserConfigParams::m_fullscreen, UserConfigParams::m_fullscreen,
false, // stencil buffers false, // stencil buffers
false, // vsync false, // vsync
this // event receiver this, // event receiver
file_manager->getFileSystem()
); );
if (m_device) if (m_device)
{ {
@ -485,10 +491,6 @@ void IrrDriver::initDevice()
m_video_driver->beginScene(/*backBuffer clear*/true, /* Z */ false); m_video_driver->beginScene(/*backBuffer clear*/true, /* Z */ false);
m_video_driver->endScene(); m_video_driver->endScene();
// Stores the new file system pointer.
file_manager->reInit();
if (CVS->isGLSL()) if (CVS->isGLSL())
{ {
Log::info("irr_driver", "GLSL supported."); Log::info("irr_driver", "GLSL supported.");

View File

@ -38,6 +38,13 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
namespace irr {
namespace io
{
IFileSystem* createFileSystem();
}
}
// For mkdir // For mkdir
#if !defined(WIN32) #if !defined(WIN32)
# include <sys/stat.h> # include <sys/stat.h>
@ -98,13 +105,11 @@ bool macSetBundlePathIfRelevant(std::string& data_dir)
// ============================================================================ // ============================================================================
FileManager* file_manager = 0; FileManager* file_manager = 0;
/** With irrlicht the constructor creates a NULL device. This is necessary to /** The constructor of the file manager creates an irrlicht file system and
* handle the Chicken/egg problem with irrlicht: access to the file system * detects paths for the user config file and assets base directory (data).
* is given from the device, but we can't create the device before reading * A second initialisation is done later once (see init()), once the user
* the user_config file (for resolution, fullscreen). So we create a dummy * config file is read. This is necessary since part of discoverPaths
* device here to begin with, which is then later (once the real device * depend on artist debug mode.
* exists) changed in reInit().
*
*/ */
FileManager::FileManager() FileManager::FileManager()
{ {
@ -135,8 +140,7 @@ FileManager::FileManager()
chdir( buffer ); chdir( buffer );
#endif #endif
m_file_system = irr_driver->getDevice()->getFileSystem(); m_file_system = irr::io::createFileSystem();
m_file_system->grab();
irr::io::path exe_path; irr::io::path exe_path;
@ -268,27 +272,16 @@ void FileManager::discoverPaths()
if(was_error) if(was_error)
Log::fatal("[FileManager]", "Not all assets found - aborting."); Log::fatal("[FileManager]", "Not all assets found - aborting.");
} // discoverPaths } // discoverPaths
//-----------------------------------------------------------------------------
/** Remove the dummy file system (which is called from IrrDriver before
* creating the actual device.
*/
void FileManager::dropFileSystem()
{
m_file_system->drop();
} // dropFileSystem
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** This function is used to re-initialise the file-manager after reading in /** This function is used to initialise the file-manager after reading in
* the user configuration data. * the user configuration data. Esp. discovering the paths of all assets
*/ * depends on the user config file (artist debug mode).
void FileManager::reInit() */
void FileManager::init()
{ {
m_file_system = irr_driver->getDevice()->getFileSystem(); discoverPaths();
m_file_system->grab();
// Note that we can't push the texture search path in the constructor // Note that we can't push the texture search path in the constructor
// since this also adds a file archive to the file system - and // since this also adds a file archive to the file system - and
// m_file_system is deleted (in irr_driver) // m_file_system is deleted (in irr_driver)
@ -298,7 +291,6 @@ void FileManager::reInit()
pushTextureSearchPath(m_subdir_name[GUI]); pushTextureSearchPath(m_subdir_name[GUI]);
pushModelSearchPath (m_subdir_name[MODEL]); pushModelSearchPath (m_subdir_name[MODEL]);
pushMusicSearchPath (m_subdir_name[MUSIC]); pushMusicSearchPath (m_subdir_name[MUSIC]);
@ -310,7 +302,7 @@ void FileManager::reInit()
for(int i=0;i<(int)dirs.size(); i++) for(int i=0;i<(int)dirs.size(); i++)
pushMusicSearchPath(dirs[i]); pushMusicSearchPath(dirs[i]);
} }
} // reInit } // init
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
FileManager::~FileManager() FileManager::~FileManager()

View File

@ -96,6 +96,7 @@ private:
void checkAndCreateScreenshotDir(); void checkAndCreateScreenshotDir();
void checkAndCreateCachedTexturesDir(); void checkAndCreateCachedTexturesDir();
void checkAndCreateGPDir(); void checkAndCreateGPDir();
void discoverPaths();
#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__APPLE__) #if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__APPLE__)
std::string checkAndCreateLinuxDir(const char *env_name, std::string checkAndCreateLinuxDir(const char *env_name,
const char *dir_name, const char *dir_name,
@ -106,9 +107,7 @@ private:
public: public:
FileManager(); FileManager();
~FileManager(); ~FileManager();
void reInit(); void init();
void discoverPaths();
void dropFileSystem();
static void addRootDirs(const std::string &roots); static void addRootDirs(const std::string &roots);
io::IXMLReader *createXMLReader(const std::string &filename); io::IXMLReader *createXMLReader(const std::string &filename);
XMLNode *createXMLTree(const std::string &filename); XMLNode *createXMLTree(const std::string &filename);
@ -149,6 +148,9 @@ public:
bool fileIsNewer(const std::string& f1, const std::string& f2) const; bool fileIsNewer(const std::string& f1, const std::string& f2) const;
// ------------------------------------------------------------------------
/** Returns the irrlicht file system. */
irr::io::IFileSystem* getFileSystem() { return m_file_system; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Adds a directory to the music search path (or stack). /** Adds a directory to the music search path (or stack).
*/ */

View File

@ -989,11 +989,13 @@ int handleCmdLine()
*/ */
void initUserConfig() void initUserConfig()
{ {
irr_driver = new IrrDriver(); file_manager = new FileManager();
file_manager = new FileManager();
user_config = new UserConfig(); // needs file_manager user_config = new UserConfig(); // needs file_manager
user_config->loadConfig(); user_config->loadConfig();
file_manager->discoverPaths(); // Some parts of the file manager needs user config (paths for models
// depend on artist debug flag). So init the rest of the file manager
// after reading the user config file.
file_manager->init();
if (UserConfigParams::m_language.toString() != "system") if (UserConfigParams::m_language.toString() != "system")
{ {
#ifdef WIN32 #ifdef WIN32
@ -1008,7 +1010,6 @@ void initUserConfig()
translations = new Translations(); // needs file_manager translations = new Translations(); // needs file_manager
stk_config = new STKConfig(); // in case of --stk-config stk_config = new STKConfig(); // in case of --stk-config
// command line parameters // command line parameters
} // initUserConfig } // initUserConfig
//============================================================================= //=============================================================================
@ -1016,6 +1017,8 @@ void initRest()
{ {
stk_config->load(file_manager->getAsset("stk_config.xml")); stk_config->load(file_manager->getAsset("stk_config.xml"));
irr_driver = new IrrDriver();
// Now create the actual non-null device in the irrlicht driver // Now create the actual non-null device in the irrlicht driver
irr_driver->initDevice(); irr_driver->initDevice();
@ -1409,6 +1412,8 @@ int main(int argc, char *argv[] )
} }
#endif #endif
delete file_manager;
return 0 ; return 0 ;
} // main } // main
@ -1509,6 +1514,6 @@ static void cleanUserConfig()
delete user_config; delete user_config;
} }
if(file_manager) delete file_manager;
if(irr_driver) delete irr_driver; if(irr_driver) delete irr_driver;
} } // cleanUserConfig