From 93a3e6c3da8274b2bb43cbde485e11fe61626e68 Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 6 Jan 2015 07:48:32 +1100 Subject: [PATCH] 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). --- lib/irrlicht/include/SIrrCreationParameters.h | 8 +++- lib/irrlicht/include/irrlicht.h | 3 +- .../source/Irrlicht/CIrrDeviceStub.cpp | 11 ++++- lib/irrlicht/source/Irrlicht/Irrlicht.cpp | 4 +- src/graphics/irr_driver.cpp | 20 ++++---- src/io/file_manager.cpp | 48 ++++++++----------- src/io/file_manager.hpp | 8 ++-- src/main.cpp | 17 ++++--- 8 files changed, 68 insertions(+), 51 deletions(-) diff --git a/lib/irrlicht/include/SIrrCreationParameters.h b/lib/irrlicht/include/SIrrCreationParameters.h index cbf558dd0..a0bc65277 100644 --- a/lib/irrlicht/include/SIrrCreationParameters.h +++ b/lib/irrlicht/include/SIrrCreationParameters.h @@ -13,6 +13,7 @@ namespace irr { class IEventReceiver; + namespace io{ class IFileSystem; } //! Structure for holding Irrlicht Device creation parameters. /** This structure is used in the createDeviceEx() function. */ @@ -35,7 +36,8 @@ namespace irr IgnoreInput(false), Stereobuffer(false), HighPrecisionFPU(false), - EventReceiver(0), + EventReceiver(NULL), + FileSystem(NULL), WindowId(0), #ifdef _DEBUG LoggingLevel(ELL_DEBUG), @@ -71,6 +73,7 @@ namespace irr Stereobuffer = other.Stereobuffer; HighPrecisionFPU = other.HighPrecisionFPU; EventReceiver = other.EventReceiver; + FileSystem = other.FileSystem; WindowId = other.WindowId; LoggingLevel = other.LoggingLevel; DriverMultithreaded = other.DriverMultithreaded; @@ -205,6 +208,9 @@ namespace irr //! A user created event receiver. IEventReceiver* EventReceiver; + //! A pointer to an existing file system to be used. + io::IFileSystem *FileSystem; + //! Window Id. /** If this is set to a value other than 0, the Irrlicht Engine will be created in an already existing window. For windows, set diff --git a/lib/irrlicht/include/irrlicht.h b/lib/irrlicht/include/irrlicht.h index 74783cebe..78415c6bb 100644 --- a/lib/irrlicht/include/irrlicht.h +++ b/lib/irrlicht/include/irrlicht.h @@ -329,7 +329,8 @@ namespace irr bool fullscreen = false, bool stencilbuffer = false, bool vsync = false, - IEventReceiver* receiver = 0); + IEventReceiver* receiver = 0, + io::IFileSystem *file_system = NULL); //! typedef for Function Pointer typedef IrrlichtDevice* (IRRCALLCONV *funcptr_createDevice )( diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceStub.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceStub.cpp index ce5fc7d38..3ae35b2b6 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceStub.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceStub.cpp @@ -40,8 +40,15 @@ CIrrDeviceStub::CIrrDeviceStub(const SIrrlichtCreationParameters& params) os::Printer::Logger = Logger; Randomizer = createDefaultRandomizer(); - FileSystem = io::createFileSystem(); - core::stringc s = "Irrlicht Engine version "; + // If the user supplies a file system, use it instead of creating a new one + if (params.FileSystem) + { + FileSystem = params.FileSystem; + FileSystem->grab(); + } + else + FileSystem = io::createFileSystem(); + core::stringc s = "Irrlicht Engine version "; s.append(getVersion()); os::Printer::log(s.c_str(), ELL_INFORMATION); diff --git a/lib/irrlicht/source/Irrlicht/Irrlicht.cpp b/lib/irrlicht/source/Irrlicht/Irrlicht.cpp index 458b246fa..9539a8bd5 100644 --- a/lib/irrlicht/source/Irrlicht/Irrlicht.cpp +++ b/lib/irrlicht/source/Irrlicht/Irrlicht.cpp @@ -48,7 +48,8 @@ namespace irr IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDevice(video::E_DRIVER_TYPE driverType, const core::dimension2d& windowSize, u32 bits, bool fullscreen, - bool stencilbuffer, bool vsync, IEventReceiver* res) + bool stencilbuffer, bool vsync, IEventReceiver* res, + io::IFileSystem *file_system) { SIrrlichtCreationParameters p; p.DriverType = driverType; @@ -58,6 +59,7 @@ namespace irr p.Stencilbuffer = stencilbuffer; p.Vsync = vsync; p.EventReceiver = res; + p.FileSystem = file_system; return createDeviceEx(p); } diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 1d87882ab..e064ccfaa 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -109,8 +109,14 @@ IrrDriver::IrrDriver() { m_resolution_changing = RES_CHANGE_NONE; m_phase = SOLID_NORMAL_AND_DEPTH_PASS; - m_device = createDevice(video::EDT_NULL); - m_request_screenshot = false; + m_device = createDevice(video::EDT_NULL, + irr::core::dimension2d(640, 480), + /*bits*/16U, /**fullscreen*/ false, + /*stencilBuffer*/ false, + /*vsync*/false, + /*event receiver*/ NULL, + file_manager->getFileSystem()); + m_request_screenshot = false; m_shaders = NULL; m_rtts = NULL; m_post_processing = NULL; @@ -390,8 +396,6 @@ void IrrDriver::initDevice() // the problem for now. m_device->clearSystemMessages(); m_device->run(); - // Clear the pointer stored in the file manager - file_manager->dropFileSystem(); m_device->drop(); m_device = NULL; @@ -410,6 +414,7 @@ void IrrDriver::initDevice() params.EventReceiver = this; params.Fullscreen = UserConfigParams::m_fullscreen; params.Vsync = UserConfigParams::m_vsync; + params.FileSystem = file_manager->getFileSystem(); params.WindowSize = core::dimension2du(UserConfigParams::m_width, UserConfigParams::m_height); @@ -456,7 +461,8 @@ void IrrDriver::initDevice() UserConfigParams::m_fullscreen, false, // stencil buffers false, // vsync - this // event receiver + this, // event receiver + file_manager->getFileSystem() ); if (m_device) { @@ -485,10 +491,6 @@ void IrrDriver::initDevice() m_video_driver->beginScene(/*backBuffer clear*/true, /* Z */ false); m_video_driver->endScene(); - // Stores the new file system pointer. - file_manager->reInit(); - - if (CVS->isGLSL()) { Log::info("irr_driver", "GLSL supported."); diff --git a/src/io/file_manager.cpp b/src/io/file_manager.cpp index ee6e18629..d60c633a9 100644 --- a/src/io/file_manager.cpp +++ b/src/io/file_manager.cpp @@ -38,6 +38,13 @@ #include #include +namespace irr { + namespace io + { + IFileSystem* createFileSystem(); + } +} + // For mkdir #if !defined(WIN32) # include @@ -98,13 +105,11 @@ bool macSetBundlePathIfRelevant(std::string& data_dir) // ============================================================================ FileManager* file_manager = 0; -/** With irrlicht the constructor creates a NULL device. This is necessary to - * handle the Chicken/egg problem with irrlicht: access to the file system - * is given from the device, but we can't create the device before reading - * the user_config file (for resolution, fullscreen). So we create a dummy - * device here to begin with, which is then later (once the real device - * exists) changed in reInit(). - * +/** The constructor of the file manager creates an irrlicht file system and + * detects paths for the user config file and assets base directory (data). + * A second initialisation is done later once (see init()), once the user + * config file is read. This is necessary since part of discoverPaths + * depend on artist debug mode. */ FileManager::FileManager() { @@ -135,8 +140,7 @@ FileManager::FileManager() chdir( buffer ); #endif - m_file_system = irr_driver->getDevice()->getFileSystem(); - m_file_system->grab(); + m_file_system = irr::io::createFileSystem(); irr::io::path exe_path; @@ -268,27 +272,16 @@ void FileManager::discoverPaths() if(was_error) Log::fatal("[FileManager]", "Not all assets found - aborting."); - } // 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 - * the user configuration data. -*/ -void FileManager::reInit() +/** This function is used to initialise the file-manager after reading in + * the user configuration data. Esp. discovering the paths of all assets + * depends on the user config file (artist debug mode). + */ +void FileManager::init() { - m_file_system = irr_driver->getDevice()->getFileSystem(); - m_file_system->grab(); - + discoverPaths(); // 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 // m_file_system is deleted (in irr_driver) @@ -298,7 +291,6 @@ void FileManager::reInit() pushTextureSearchPath(m_subdir_name[GUI]); - pushModelSearchPath (m_subdir_name[MODEL]); pushMusicSearchPath (m_subdir_name[MUSIC]); @@ -310,7 +302,7 @@ void FileManager::reInit() for(int i=0;i<(int)dirs.size(); i++) pushMusicSearchPath(dirs[i]); } -} // reInit +} // init //----------------------------------------------------------------------------- FileManager::~FileManager() diff --git a/src/io/file_manager.hpp b/src/io/file_manager.hpp index d52e7fd7a..8ae5792bc 100644 --- a/src/io/file_manager.hpp +++ b/src/io/file_manager.hpp @@ -96,6 +96,7 @@ private: void checkAndCreateScreenshotDir(); void checkAndCreateCachedTexturesDir(); void checkAndCreateGPDir(); + void discoverPaths(); #if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__APPLE__) std::string checkAndCreateLinuxDir(const char *env_name, const char *dir_name, @@ -106,9 +107,7 @@ private: public: FileManager(); ~FileManager(); - void reInit(); - void discoverPaths(); - void dropFileSystem(); + void init(); static void addRootDirs(const std::string &roots); io::IXMLReader *createXMLReader(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; + // ------------------------------------------------------------------------ + /** Returns the irrlicht file system. */ + irr::io::IFileSystem* getFileSystem() { return m_file_system; } // ------------------------------------------------------------------------ /** Adds a directory to the music search path (or stack). */ diff --git a/src/main.cpp b/src/main.cpp index a671e53e1..4aa7beec4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -989,11 +989,13 @@ int handleCmdLine() */ void initUserConfig() { - irr_driver = new IrrDriver(); - file_manager = new FileManager(); + file_manager = new FileManager(); user_config = new UserConfig(); // needs file_manager 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") { #ifdef WIN32 @@ -1008,7 +1010,6 @@ void initUserConfig() translations = new Translations(); // needs file_manager stk_config = new STKConfig(); // in case of --stk-config // command line parameters - } // initUserConfig //============================================================================= @@ -1016,6 +1017,8 @@ void initRest() { stk_config->load(file_manager->getAsset("stk_config.xml")); + irr_driver = new IrrDriver(); + // Now create the actual non-null device in the irrlicht driver irr_driver->initDevice(); @@ -1409,6 +1412,8 @@ int main(int argc, char *argv[] ) } #endif + delete file_manager; + return 0 ; } // main @@ -1509,6 +1514,6 @@ static void cleanUserConfig() delete user_config; } - if(file_manager) delete file_manager; if(irr_driver) delete irr_driver; -} +} // cleanUserConfig +