Browse Source

Ensure the application logs are created in a writeable location.

- Add a new function to get application preferences directory and expose it to scripting.
- Change Editor to save/load configuration file from the application preferences directory.
- Standardized the location of log files generated by Urho3DPlayer and samples. Ensure it is created in a user writeable location to prevent application locked up during closing.
Yao Wei Tjong 姚伟忠 11 years ago
parent
commit
96295b4923

+ 1 - 21
Bin/Data/Scripts/Editor.as

@@ -15,8 +15,6 @@
 #include "Scripts/Editor/EditorImport.as"
 #include "Scripts/Editor/EditorImport.as"
 #include "Scripts/Editor/EditorSpawn.as"
 #include "Scripts/Editor/EditorSpawn.as"
 
 
-
-String configPath;
 String configFileName;
 String configFileName;
 
 
 bool instancingSetting = true;
 bool instancingSetting = true;
@@ -25,12 +23,7 @@ int shadowQualitySetting = 2;
 void Start()
 void Start()
 {
 {
     // Assign the value ASAP because configFileName is needed on exit, including exit on error
     // Assign the value ASAP because configFileName is needed on exit, including exit on error
-    if (GetPlatform() == "Windows")
-        configPath = "Urho3D/Editor/";
-    else
-        // Unix-like platforms usually hide application configuration file
-        configPath = ".Urho3D/Editor/";
-    configFileName = fileSystem.userDocumentsDir + configPath + "Config.xml";
+    configFileName = fileSystem.GetAppPreferencesDir("urho3d", "Editor") + "Config.xml";
 
 
     if (engine.headless)
     if (engine.headless)
     {
     {
@@ -236,8 +229,6 @@ void LoadConfig()
 
 
 void SaveConfig()
 void SaveConfig()
 {
 {
-    CreateDir(configPath);
-
     XMLFile config;
     XMLFile config;
     XMLElement configElem = config.CreateRoot("configuration");
     XMLElement configElem = config.CreateRoot("configuration");
     XMLElement cameraElem = configElem.CreateChild("camera");
     XMLElement cameraElem = configElem.CreateChild("camera");
@@ -319,14 +310,3 @@ void SaveConfig()
 
 
     config.Save(File(configFileName, FILE_WRITE));
     config.Save(File(configFileName, FILE_WRITE));
 }
 }
-
-void CreateDir(const String&in pathName, const String&in baseDir = fileSystem.userDocumentsDir)
-{
-    Array<String> dirs = pathName.Split('/');
-    String subdir = baseDir;
-    for (uint i = 0; i < dirs.length; ++i)
-    {
-        subdir += dirs[i] + "/";
-        fileSystem.CreateDir(subdir);
-    }
-}

+ 16 - 1
Source/Engine/IO/FileSystem.cpp

@@ -77,7 +77,7 @@ int DoSystemCommand(const String& commandLine, bool redirectToLog, Context* cont
     // Get a platform-agnostic temporary file name for stderr redirection
     // Get a platform-agnostic temporary file name for stderr redirection
     String stderrFilename;
     String stderrFilename;
     String adjustedCommandLine(commandLine);
     String adjustedCommandLine(commandLine);
-    char* prefPath = SDL_GetPrefPath("urho3d", "Urho3D");
+    char* prefPath = SDL_GetPrefPath("urho3d", "temp");
     if (prefPath)
     if (prefPath)
     {
     {
         stderrFilename = String(prefPath) + "command-stderr";
         stderrFilename = String(prefPath) + "command-stderr";
@@ -697,6 +697,21 @@ String FileSystem::GetUserDocumentsDir() const
     #endif
     #endif
 }
 }
 
 
+String FileSystem::GetAppPreferencesDir(const String& org, const String& app) const
+{
+    String dir;
+    char* prefPath = SDL_GetPrefPath(org.CString(), app.CString());
+    if (prefPath)
+    {
+        dir = String(prefPath);
+        SDL_free(prefPath);
+    }
+    else
+        LOGWARNING("Could not get application preferences directory");
+
+    return dir;
+}
+
 void FileSystem::RegisterPath(const String& pathName)
 void FileSystem::RegisterPath(const String& pathName)
 {
 {
     if (pathName.Empty())
     if (pathName.Empty())

+ 2 - 0
Source/Engine/IO/FileSystem.h

@@ -94,6 +94,8 @@ public:
     String GetProgramDir() const;
     String GetProgramDir() const;
     /// Return the user documents directory.
     /// Return the user documents directory.
     String GetUserDocumentsDir() const;
     String GetUserDocumentsDir() const;
+    /// Return the application preferences directory.
+    String GetAppPreferencesDir(const String& org, const String& app) const;
     
     
 private:
 private:
     /// Scan directory, called internally.
     /// Scan directory, called internally.

+ 1 - 0
Source/Engine/LuaScript/pkgs/IO/FileSystem.pkg

@@ -30,6 +30,7 @@ class FileSystem : public Object
     
     
     String GetProgramDir() const;
     String GetProgramDir() const;
     String GetUserDocumentsDir() const;
     String GetUserDocumentsDir() const;
+    String GetAppPreferencesDir(const String org, const String app) const;
 };
 };
 
 
 String GetPath(const String fullPath);
 String GetPath(const String fullPath);

+ 1 - 0
Source/Engine/Script/IOAPI.cpp

@@ -339,6 +339,7 @@ void RegisterFileSystem(asIScriptEngine* engine)
     engine->RegisterObjectMethod("FileSystem", "bool Copy(const String&in, const String&in)", asMETHOD(FileSystem, Copy), asCALL_THISCALL);
     engine->RegisterObjectMethod("FileSystem", "bool Copy(const String&in, const String&in)", asMETHOD(FileSystem, Copy), asCALL_THISCALL);
     engine->RegisterObjectMethod("FileSystem", "bool Rename(const String&in, const String&in)", asMETHOD(FileSystem, Rename), asCALL_THISCALL);
     engine->RegisterObjectMethod("FileSystem", "bool Rename(const String&in, const String&in)", asMETHOD(FileSystem, Rename), asCALL_THISCALL);
     engine->RegisterObjectMethod("FileSystem", "bool Delete(const String&in)", asMETHOD(FileSystem, Delete), asCALL_THISCALL);
     engine->RegisterObjectMethod("FileSystem", "bool Delete(const String&in)", asMETHOD(FileSystem, Delete), asCALL_THISCALL);
+    engine->RegisterObjectMethod("FileSystem", "String GetAppPreferencesDir(const String&in org, const String&in app) const", asMETHOD(FileSystem, GetAppPreferencesDir), asCALL_THISCALL);
     engine->RegisterObjectMethod("FileSystem", "String get_currentDir() const", asMETHOD(FileSystem, GetCurrentDir), asCALL_THISCALL);
     engine->RegisterObjectMethod("FileSystem", "String get_currentDir() const", asMETHOD(FileSystem, GetCurrentDir), asCALL_THISCALL);
     engine->RegisterObjectMethod("FileSystem", "void set_currentDir(const String&in)", asMETHOD(FileSystem, SetCurrentDir), asCALL_THISCALL);
     engine->RegisterObjectMethod("FileSystem", "void set_currentDir(const String&in)", asMETHOD(FileSystem, SetCurrentDir), asCALL_THISCALL);
     engine->RegisterObjectMethod("FileSystem", "void set_executeConsoleCommands(bool)", asMETHOD(FileSystem, SetExecuteConsoleCommands), asCALL_THISCALL);
     engine->RegisterObjectMethod("FileSystem", "void set_executeConsoleCommands(bool)", asMETHOD(FileSystem, SetExecuteConsoleCommands), asCALL_THISCALL);

+ 1 - 1
Source/Samples/Sample.inl

@@ -55,7 +55,7 @@ void Sample::Setup()
 {
 {
     // Modify engine startup parameters
     // Modify engine startup parameters
     engineParameters_["WindowTitle"] = GetTypeName();
     engineParameters_["WindowTitle"] = GetTypeName();
-    engineParameters_["LogName"]     = GetTypeName() + ".log";
+    engineParameters_["LogName"]     = GetSubsystem<FileSystem>()->GetAppPreferencesDir("urho3d", "logs") + GetTypeName() + ".log";
     engineParameters_["FullScreen"]  = false;
     engineParameters_["FullScreen"]  = false;
     engineParameters_["Headless"]    = false;
     engineParameters_["Headless"]    = false;
 }
 }

+ 8 - 1
Source/Tools/Urho3DPlayer/Urho3DPlayer.cpp

@@ -50,9 +50,11 @@ Urho3DPlayer::Urho3DPlayer(Context* context) :
 
 
 void Urho3DPlayer::Setup()
 void Urho3DPlayer::Setup()
 {
 {
+    FileSystem* filesystem = GetSubsystem<FileSystem>();
+
     // On Android and iOS, read command line from a file as parameters can not otherwise be easily given
     // On Android and iOS, read command line from a file as parameters can not otherwise be easily given
     #if defined(ANDROID) || defined(IOS)
     #if defined(ANDROID) || defined(IOS)
-    SharedPtr<File> commandFile(new File(context_, GetSubsystem<FileSystem>()->GetProgramDir() + "Data/CommandLine.txt",
+    SharedPtr<File> commandFile(new File(context_, filesystem->GetProgramDir() + "Data/CommandLine.txt",
         FILE_READ));
         FILE_READ));
     String commandLine = commandFile->ReadLine();
     String commandLine = commandFile->ReadLine();
     commandFile->Close();
     commandFile->Close();
@@ -117,6 +119,11 @@ void Urho3DPlayer::Setup()
             #endif
             #endif
         );
         );
     }
     }
+    else
+    {
+        // Use the script file name as the base name for the log file
+        engineParameters_["LogName"] = filesystem->GetAppPreferencesDir("urho3d", "logs") + GetFileNameAndExtension(scriptFileName_) + ".log";
+    }
 }
 }
 
 
 void Urho3DPlayer::Start()
 void Urho3DPlayer::Start()