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
{
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

View File

@ -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 )(

View File

@ -40,6 +40,13 @@ CIrrDeviceStub::CIrrDeviceStub(const SIrrlichtCreationParameters& params)
os::Printer::Logger = Logger;
Randomizer = createDefaultRandomizer();
// 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());

View File

@ -48,7 +48,8 @@ namespace irr
IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDevice(video::E_DRIVER_TYPE driverType,
const core::dimension2d<u32>& 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);
}

View File

@ -109,7 +109,13 @@ IrrDriver::IrrDriver()
{
m_resolution_changing = RES_CHANGE_NONE;
m_phase = SOLID_NORMAL_AND_DEPTH_PASS;
m_device = createDevice(video::EDT_NULL);
m_device = createDevice(video::EDT_NULL,
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_rtts = 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.");

View File

@ -38,6 +38,13 @@
#include <iostream>
#include <string>
namespace irr {
namespace io
{
IFileSystem* createFileSystem();
}
}
// For mkdir
#if !defined(WIN32)
# include <sys/stat.h>
@ -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()

View File

@ -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).
*/

View File

@ -989,11 +989,13 @@ int handleCmdLine()
*/
void initUserConfig()
{
irr_driver = new IrrDriver();
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