yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Ellie Hermaszewskaformatf65d756bf

master
6.0 KiB207 linesraw
1// slang-include-system.cpp
2#include "slang-include-system.h"
3
4#include "../core/slang-file-system.h"
5#include "../core/slang-io.h"
6#include "../core/slang-string-util.h"
7#include "slang-artifact-impl.h"
8#include "slang-artifact-representation-impl.h"
9#include "slang-slice-allocator.h"
10
11namespace Slang
12{
13
14IncludeSystem::IncludeSystem(
15    SearchDirectoryList* searchDirectories,
16    ISlangFileSystemExt* fileSystemExt,
17    SourceManager* sourceManager)
18    : m_searchDirectories(searchDirectories)
19    , m_fileSystemExt(fileSystemExt)
20    , m_sourceManager(sourceManager)
21{
22}
23
24SlangResult IncludeSystem::findFile(
25    SlangPathType fromPathType,
26    const String& fromPath,
27    const String& path,
28    PathInfo& outPathInfo)
29{
30    String combinedPath;
31
32    if (fromPath.getLength() == 0 || Path::isAbsolute(path))
33    {
34        // If the path is absolute or the fromPath is empty, the combined path is just the path
35        combinedPath = path;
36    }
37    else
38    {
39        // Get relative path
40        ComPtr<ISlangBlob> combinedPathBlob;
41        SLANG_RETURN_ON_FAIL(m_fileSystemExt->calcCombinedPath(
42            fromPathType,
43            fromPath.begin(),
44            path.begin(),
45            combinedPathBlob.writeRef()));
46        combinedPath = StringUtil::getString(combinedPathBlob);
47        if (combinedPath.getLength() <= 0)
48        {
49            return SLANG_FAIL;
50        }
51    }
52
53    // This checks the path exists
54    SlangPathType pathType;
55    SLANG_RETURN_ON_FAIL(m_fileSystemExt->getPathType(combinedPath.begin(), &pathType));
56    if (pathType != SLANG_PATH_TYPE_FILE)
57    {
58        return SLANG_E_NOT_FOUND;
59    }
60
61    // Get the uniqueIdentity
62    ComPtr<ISlangBlob> uniqueIdentityBlob;
63    SLANG_RETURN_ON_FAIL(m_fileSystemExt->getFileUniqueIdentity(
64        combinedPath.begin(),
65        uniqueIdentityBlob.writeRef()));
66
67    // If the rel path exists -> a uniqueIdentity MUST exists too
68    String uniqueIdentity(StringUtil::getString(uniqueIdentityBlob));
69    if (uniqueIdentity.getLength() <= 0)
70    {
71        // Unique identity can't be empty
72        return SLANG_FAIL;
73    }
74
75    outPathInfo = PathInfo::makeNormal(combinedPath, uniqueIdentity);
76    return SLANG_OK;
77}
78
79String IncludeSystem::simplifyPath(const String& path)
80{
81    ComPtr<ISlangBlob> simplifiedPath;
82    if (SLANG_FAILED(m_fileSystemExt->getPath(
83            PathKind::Simplified,
84            path.getBuffer(),
85            simplifiedPath.writeRef())))
86    {
87        return path;
88    }
89    return StringUtil::getString(simplifiedPath);
90}
91
92SlangResult IncludeSystem::findFile(
93    String const& pathToInclude,
94    String const& pathIncludedFrom,
95    PathInfo& outPathInfo)
96{
97    outPathInfo.type = PathInfo::Type::Unknown;
98
99    // If it's absolute we only have to try and find if it's there - no need to look at search paths
100    if (Path::isAbsolute(pathToInclude))
101    {
102        // We pass in "" as the from path, so ensure no from path is taken into account
103        // and to allow easy identification that this is in effect absolute
104        return findFile(
105            SLANG_PATH_TYPE_DIRECTORY,
106            UnownedStringSlice::fromLiteral(""),
107            pathToInclude,
108            outPathInfo);
109    }
110
111    // Try just relative to current path
112    {
113        SlangResult res =
114            findFile(SLANG_PATH_TYPE_FILE, pathIncludedFrom, pathToInclude, outPathInfo);
115        // It either succeeded or wasn't found, anything else is a failure passed back
116        if (SLANG_SUCCEEDED(res) || res != SLANG_E_NOT_FOUND)
117        {
118            return res;
119        }
120    }
121
122    // Search all the searchDirectories
123    for (auto sd = m_searchDirectories; sd; sd = sd->parent)
124    {
125        for (auto& dir : sd->searchDirectories)
126        {
127            SlangResult res =
128                findFile(SLANG_PATH_TYPE_DIRECTORY, dir.path, pathToInclude, outPathInfo);
129            if (SLANG_SUCCEEDED(res) || res != SLANG_E_NOT_FOUND)
130            {
131                return res;
132            }
133        }
134    }
135
136    return SLANG_E_NOT_FOUND;
137}
138
139SlangResult IncludeSystem::loadFile(
140    const PathInfo& pathInfo,
141    ComPtr<ISlangBlob>& outBlob,
142    SourceFile*& outSourceFile)
143{
144    if (m_sourceManager)
145    {
146        // See if this an already loaded source file
147        outSourceFile = m_sourceManager->findSourceFileRecursively(pathInfo.uniqueIdentity);
148
149        // If not create a new one, and add to the list of known source files
150        if (!outSourceFile)
151        {
152            ComPtr<ISlangBlob> foundSourceBlob;
153            if (SLANG_FAILED(m_fileSystemExt->loadFile(
154                    pathInfo.foundPath.getBuffer(),
155                    foundSourceBlob.writeRef())))
156            {
157                return SLANG_E_CANNOT_OPEN;
158            }
159
160            outSourceFile = m_sourceManager->createSourceFileWithBlob(pathInfo, foundSourceBlob);
161            m_sourceManager->addSourceFile(pathInfo.uniqueIdentity, outSourceFile);
162
163            outBlob = foundSourceBlob;
164            return SLANG_OK;
165        }
166        else
167        {
168            if (outSourceFile->getContentBlob())
169            {
170                outBlob = outSourceFile->getContentBlob();
171                return SLANG_OK;
172            }
173
174            ComPtr<ISlangBlob> foundSourceBlob;
175            if (SLANG_FAILED(m_fileSystemExt->loadFile(
176                    pathInfo.foundPath.getBuffer(),
177                    foundSourceBlob.writeRef())))
178            {
179                return SLANG_E_CANNOT_OPEN;
180            }
181
182            outSourceFile->setContents(foundSourceBlob);
183
184            outBlob = foundSourceBlob;
185            return SLANG_OK;
186        }
187    }
188    else
189    {
190        // If we don't have the source manager, just load
191        outSourceFile = nullptr;
192        return m_fileSystemExt->loadFile(pathInfo.foundPath.getBuffer(), outBlob.writeRef());
193    }
194}
195
196SlangResult IncludeSystem::findAndLoadFile(
197    const String& pathToInclude,
198    const String& pathIncludedFrom,
199    PathInfo& outPathInfo,
200    ComPtr<ISlangBlob>& outBlob)
201{
202    SLANG_RETURN_ON_FAIL(findFile(pathToInclude, pathIncludedFrom, outPathInfo));
203    SLANG_RETURN_ON_FAIL(loadFile(outPathInfo, outBlob));
204    return SLANG_OK;
205}
206
207} // namespace Slang