yum-mirror/slang

Making it easier to work with shaders

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

Ellie Hermaszewskaformatf65d756bf

master
5.4 KiB167 linesraw
1#include "slang-filesystem.h"
2
3#include "../../core/slang-io.h"
4#include "../util/record-utility.h"
5#include "output-stream.h"
6
7#include <stdlib.h>
8
9namespace SlangRecord
10{
11// We don't actually need to record the methods of ISlangFileSystemExt, we just want to record the
12// file content and save them into disk.
13FileSystemRecorder::FileSystemRecorder(
14    ISlangFileSystemExt* fileSystem,
15    RecordManager* recordManager)
16    : m_actualFileSystem(fileSystem), m_recordManager(recordManager)
17{
18    SLANG_RECORD_ASSERT(m_actualFileSystem);
19    SLANG_RECORD_ASSERT(m_recordManager);
20    slangRecordLog(LogLevel::Verbose, "%s: %p\n", __PRETTY_FUNCTION__, m_actualFileSystem.get());
21}
22
23void* FileSystemRecorder::castAs(const Slang::Guid& guid)
24{
25    return getInterface(guid);
26}
27
28ISlangUnknown* FileSystemRecorder::getInterface(const Slang::Guid& guid)
29{
30    if (guid == ISlangUnknown::getTypeGuid() || guid == ISlangFileSystem::getTypeGuid())
31        return static_cast<ISlangFileSystem*>(this);
32    return nullptr;
33}
34
35// TODO: There could be a potential issue that could not be able to dump the generated file content
36// correctly. Details: https://github.com/shader-slang/slang/issues/4423.
37SLANG_NO_THROW SlangResult FileSystemRecorder::loadFile(char const* path, ISlangBlob** outBlob)
38{
39    slangRecordLog(
40        LogLevel::Verbose,
41        "%p: %s, :%s\n",
42        m_actualFileSystem.get(),
43        __PRETTY_FUNCTION__,
44        path);
45    SlangResult res = m_actualFileSystem->loadFile(path, outBlob);
46
47    // Since the loadFile method could be implemented by client, we can't guarantee the result is
48    // always as expected, we will check every thing to make sure we won't crash at writing file.
49    //
50    // We can only dump the file content after this 'loadFile' call, no matter this call crashes or
51    // file is not found, we can't save the file anyway, so we don't need to pay special care to the
52    // crash recovery. We will know something wrong with the loadFile call if we can't find the file
53    // in the record directory.
54    if ((res == SLANG_OK) && (*outBlob != nullptr) && ((*outBlob)->getBufferSize() != 0))
55    {
56        Slang::String filePath =
57            Slang::Path::combine(m_recordManager->getRecordFileDirectory(), path);
58        Slang::String dirPath = Slang::Path::getParentDirectory(filePath);
59        if (!File::exists(dirPath))
60        {
61            slangRecordLog(
62                LogLevel::Debug,
63                "Create directory: %s to save captured shader file: %s\n",
64                dirPath.getBuffer(),
65                filePath.getBuffer());
66
67            if (!Path::createDirectoryRecursive(dirPath))
68            {
69                slangRecordLog(
70                    LogLevel::Error,
71                    "Fail to create directory: %s\n",
72                    dirPath.getBuffer());
73                return SLANG_FAIL;
74            }
75        }
76
77        FileOutputStream fileStream(filePath);
78
79        fileStream.write((*outBlob)->getBufferPointer(), (*outBlob)->getBufferSize());
80        fileStream.flush();
81    }
82    return res;
83}
84
85SLANG_NO_THROW SlangResult
86FileSystemRecorder::getFileUniqueIdentity(const char* path, ISlangBlob** outUniqueIdentity)
87{
88    slangRecordLog(
89        LogLevel::Verbose,
90        "%p: %s :\"%s\"\n",
91        m_actualFileSystem.get(),
92        __PRETTY_FUNCTION__,
93        path);
94    SlangResult res = m_actualFileSystem->getFileUniqueIdentity(path, outUniqueIdentity);
95    return res;
96}
97
98SLANG_NO_THROW SlangResult FileSystemRecorder::calcCombinedPath(
99    SlangPathType fromPathType,
100    const char* fromPath,
101    const char* path,
102    ISlangBlob** pathOut)
103{
104    slangRecordLog(
105        LogLevel::Verbose,
106        "%p: %s, :%s\n",
107        m_actualFileSystem.get(),
108        __PRETTY_FUNCTION__,
109        path);
110    SlangResult res = m_actualFileSystem->calcCombinedPath(fromPathType, fromPath, path, pathOut);
111    return res;
112}
113
114SLANG_NO_THROW SlangResult
115FileSystemRecorder::getPathType(const char* path, SlangPathType* pathTypeOut)
116{
117    slangRecordLog(
118        LogLevel::Verbose,
119        "%p: %s, :%s\n",
120        m_actualFileSystem.get(),
121        __PRETTY_FUNCTION__,
122        path);
123    SlangResult res = m_actualFileSystem->getPathType(path, pathTypeOut);
124    return res;
125}
126
127SLANG_NO_THROW SlangResult
128FileSystemRecorder::getPath(PathKind kind, const char* path, ISlangBlob** outPath)
129{
130    slangRecordLog(
131        LogLevel::Verbose,
132        "%p: %s, :%s\n",
133        m_actualFileSystem.get(),
134        __PRETTY_FUNCTION__,
135        path);
136    SlangResult res = m_actualFileSystem->getPath(kind, path, outPath);
137    return res;
138}
139
140SLANG_NO_THROW void FileSystemRecorder::clearCache()
141{
142    slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__);
143    m_actualFileSystem->clearCache();
144}
145
146SLANG_NO_THROW SlangResult FileSystemRecorder::enumeratePathContents(
147    const char* path,
148    FileSystemContentsCallBack callback,
149    void* userData)
150{
151    slangRecordLog(
152        LogLevel::Verbose,
153        "%p: %s, :%s\n",
154        m_actualFileSystem.get(),
155        __PRETTY_FUNCTION__,
156        path);
157    SlangResult res = m_actualFileSystem->enumeratePathContents(path, callback, userData);
158    return res;
159}
160
161SLANG_NO_THROW OSPathKind FileSystemRecorder::getOSPathKind()
162{
163    slangRecordLog(LogLevel::Verbose, "%p: %s\n", m_actualFileSystem.get(), __PRETTY_FUNCTION__);
164    OSPathKind pathKind = m_actualFileSystem->getOSPathKind();
165    return pathKind;
166}
167} // namespace SlangRecord