yum-mirror/slang

Making it easier to work with shaders

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

Jay KwakDisable Link-Time-Optimization by default (#7345)7f04adbfb

master
5.9 KiB153 linesraw
1#ifndef SLANG_CORE_MEMORY_FILE_SYSTEM_H
2#define SLANG_CORE_MEMORY_FILE_SYSTEM_H
3
4#include "slang-basic.h"
5#include "slang-com-object.h"
6#include "slang-com-ptr.h"
7
8namespace Slang
9{
10
11/* MemoryFileSystem is an implementation of ISlangMutableFileSystem that stores file contents in
12'blobs' (typically) in memory.
13
14A derived class can change how the contents of the contents blob is interpretted (so for example the
15RiffFileSystem is implemented such that the Entry.m_contents is the files contents compressed).
16
17The implementation uses a map to store the file/directory based on their canonical path. This makes
18access relatively fast and simple - an access only requires a path being converted into a canonical
19path, and then a lookup. Whilst this makes typical access fast, it means doing an enumeration of a
20directory slower as it requires traversing all entries to find which are in the path.
21
22This is in contrast with an implementation that held items in directories 'objects'. In that
23scenario the path through the hierarchy would need to be traversed to find the item. Finding all of
24the items in a directory is very fast - it's all the items held in the the directory 'object'.
25
26TODO(JS):
27* We may want to make saveFile take a blob, or have a version that does. Doing so would allow the
28application to handle memory management around the blob.
29*/
30class MemoryFileSystem : public ComBaseObject, public ISlangMutableFileSystem
31{
32public:
33    // ISlangUnknown
34    SLANG_COM_BASE_IUNKNOWN_ALL
35
36    // ISlangCastable
37    virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
38
39    // ISlangFileSystem
40    virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile(char const* path, ISlangBlob** outBlob)
41        SLANG_OVERRIDE;
42
43    // ISlangFileSystemExt
44    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
45    getFileUniqueIdentity(const char* path, ISlangBlob** uniqueIdentityOut) SLANG_OVERRIDE;
46    virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath(
47        SlangPathType fromPathType,
48        const char* fromPath,
49        const char* path,
50        ISlangBlob** pathOut) SLANG_OVERRIDE;
51    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
52    getPathType(const char* path, SlangPathType* pathTypeOut) SLANG_OVERRIDE;
53    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
54    getPath(PathKind pathKind, const char* path, ISlangBlob** outPath) SLANG_OVERRIDE;
55    virtual SLANG_NO_THROW void SLANG_MCALL clearCache() SLANG_OVERRIDE {}
56    virtual SLANG_NO_THROW SlangResult SLANG_MCALL enumeratePathContents(
57        const char* path,
58        FileSystemContentsCallBack callback,
59        void* userData) SLANG_OVERRIDE;
60    virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind() SLANG_OVERRIDE
61    {
62        return OSPathKind::None;
63    }
64
65    // ISlangModifyableFileSystem
66    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
67    saveFile(const char* path, const void* data, size_t size) SLANG_OVERRIDE;
68    virtual SLANG_NO_THROW SlangResult SLANG_MCALL
69    saveFileBlob(const char* path, ISlangBlob* dataBlob) SLANG_OVERRIDE;
70    virtual SLANG_NO_THROW SlangResult SLANG_MCALL remove(const char* path) SLANG_OVERRIDE;
71    virtual SLANG_NO_THROW SlangResult SLANG_MCALL createDirectory(const char* path) SLANG_OVERRIDE;
72
73    /// Ctor
74    MemoryFileSystem();
75
76protected:
77    struct Entry
78    {
79        void reset()
80        {
81            m_type = SLANG_PATH_TYPE_FILE;
82            m_canonicalPath = String();
83            m_uncompressedSizeInBytes = 0;
84            m_contents.setNull();
85        }
86
87        void initDirectory(const String& canonicalPath)
88        {
89            m_type = SLANG_PATH_TYPE_DIRECTORY;
90            m_canonicalPath = canonicalPath;
91            m_uncompressedSizeInBytes = 0;
92            m_contents.setNull();
93        }
94        void initFile(const String& canonicalPath, size_t uncompressedSize, ISlangBlob* blob)
95        {
96            m_type = SLANG_PATH_TYPE_FILE;
97            m_canonicalPath = canonicalPath;
98            setContents(uncompressedSize, blob);
99        }
100        void initFile(const String& canonicalPath)
101        {
102            m_type = SLANG_PATH_TYPE_FILE;
103            m_canonicalPath = canonicalPath;
104            m_contents.setNull();
105            m_uncompressedSizeInBytes = 0;
106        }
107        void setContents(size_t uncompressedSize, ISlangBlob* blob)
108        {
109            SLANG_ASSERT(m_type == SLANG_PATH_TYPE_FILE);
110            SLANG_ASSERT(blob);
111            m_uncompressedSizeInBytes = uncompressedSize;
112            m_contents = blob;
113        }
114
115        SlangPathType m_type;
116        String m_canonicalPath;
117
118        /// The size as seen on the file system. Might be different from the size of m_contents
119        /// if it's actually being stored in some other representation (such as compressed)
120        size_t m_uncompressedSizeInBytes;
121        ComPtr<ISlangBlob> m_contents; ///< Can be compressed or not
122    };
123
124    void* getInterface(const Guid& guid);
125    void* getObject(const Guid& guid);
126
127    Entry* _getEntryFromPath(const char* path, String* outPath = nullptr);
128    Entry* _getEntryFromCanonicalPath(const String& canonicalPath);
129    /// Creates or returns a file entry for the given path.
130    /// If created the entry is empty.
131    SlangResult _requireFile(const char* path, Entry** outEntry);
132    /// Given the path returns the entry if it's a file, or returns an error
133    SlangResult _loadFile(const char* path, Entry** outEntry);
134
135    /// Given a path returns a canonical path.
136    /// The canonical path must have *existing* parent paths.
137    SlangResult _getCanonicalWithExistingParent(const char* path, StringBuilder& canonicalPath);
138
139    /// Given a path returns a canonical path.
140    SlangResult _getCanonical(const char* path, StringBuilder& canonicalPath);
141
142    /// Clear, ensures any backing memory is also freed
143    void _clear();
144
145    // Maps canonical paths to an entries (which could be files or directories)
146    Dictionary<String, Entry> m_entries;
147
148    Entry m_rootEntry;
149};
150
151} // namespace Slang
152
153#endif