1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#include "BsPrerequisites.h"
4#include "BsEngineConfig.h"
5#include "FileSystem/BsFileSystem.h"
6#include "Utility/BsDynLib.h"
7
8namespace bs
9{
10 const Path Paths::RELEASE_ASSEMBLY_PATH = "bin/Assemblies/Release/";
11 const Path Paths::DEBUG_ASSEMBLY_PATH = "bin/Assemblies/Debug/";
12
13 const Path Paths::FRAMEWORK_DATA_PATH = "Data/";
14
15#if BS_INCLUDE_B3D_PATHS
16 const Path Paths::EDITOR_DATA_PATH = "EditorData/";
17#endif
18
19 const Path& Paths::getDataPath()
20 {
21 static bool initialized = false;
22 static Path path;
23
24 if(!initialized)
25 {
26 if (FileSystem::exists(FRAMEWORK_DATA_PATH))
27 path = FileSystem::getWorkingDirectoryPath() + FRAMEWORK_DATA_PATH;
28 else
29#if BS_IS_BANSHEE3D
30 path = Path(RAW_APP_ROOT) + Path("Source/bsf") + FRAMEWORK_DATA_PATH;
31#else
32 path = Path(RAW_APP_ROOT) + FRAMEWORK_DATA_PATH;
33#endif
34
35 initialized = true;
36 }
37
38 return path;
39 }
40
41 const Path& Paths::getBinariesPath()
42 {
43 static bool initialized = false;
44 static Path path;
45
46 if(!initialized)
47 {
48 path = FileSystem::getWorkingDirectoryPath();
49
50 // Look for bsf library to find the right path
51 Path anchorFile = path;
52 anchorFile.setFilename("bsf." + String(DynLib::EXTENSION));
53
54 if (!FileSystem::exists(anchorFile))
55 {
56 path = BINARIES_PATH;
57 if (!FileSystem::exists(path))
58 path = ""; // No path found, keep the default
59 }
60
61 initialized = true;
62 }
63
64 return path;
65 }
66
67#if BS_INCLUDE_B3D_PATHS
68 const Path& Paths::getEditorDataPath()
69 {
70 static bool initialized = false;
71 static Path path;
72
73 if(!initialized)
74 {
75#ifdef BS_IS_ASSET_TOOL
76 // Asset tool always runs relative to the 'bsf' directory
77 Path editorDataPath = Path("../../") + FRAMEWORK_DATA_PATH;
78
79 if (FileSystem::exists(editorDataPath))
80 path = FileSystem::getWorkingDirectoryPath() + editorDataPath;
81#else
82 // Otherwise, look for the folder in the direct descendant of the working directory
83 if (FileSystem::exists(EDITOR_DATA_PATH))
84 path = FileSystem::getWorkingDirectoryPath() + EDITOR_DATA_PATH;
85#endif
86 // Then check the source distribution itself, in case we're running directly from the build directory
87 else
88 {
89 path = Path(RAW_APP_ROOT) + FRAMEWORK_DATA_PATH;
90
91 if (!FileSystem::exists(path))
92 LOGERR("Cannot find builtin assets for the editor at path '" + path.toString() + "'.");
93 }
94
95 initialized = true;
96 }
97
98 return path;
99 }
100
101 const Path& Paths::getGameSettingsPath()
102 {
103 static Path path = findPath(GAME_SETTINGS_NAME);
104 return path;
105 }
106
107 const Path& Paths::getGameResourcesPath()
108 {
109 static Path path = findPath(GAME_RESOURCES_FOLDER_NAME);
110 return path;
111 }
112#endif
113
114 Path Paths::findPath(const Path& path)
115 {
116 // Note: These paths should be searched for during start-up and cached
117
118 // First, look for the direct descendant of the working directory
119 Path output = path;
120 if (FileSystem::exists(path))
121 {
122 output.makeAbsolute(FileSystem::getWorkingDirectoryPath());
123 return output;
124 }
125
126 // Then, check the build directory itself, in case we're running directly from it (during development)
127 output.makeAbsolute(BUILD_APP_ROOT);
128 if (FileSystem::exists(output))
129 return output;
130
131 // No path found, but return the initial value by default
132 return path;
133 }
134}