yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
7f04adbfb
master
1#ifndef SLANG_FILE_SYSTEM_H_INCLUDED 2#define SLANG_FILE_SYSTEM_H_INCLUDED 3 4#include "../core/slang-blob.h" 5#include "../core/slang-dictionary.h" 6#include "../core/slang-string-util.h" 7#include "slang-com-helper.h" 8#include "slang-com-ptr.h" 9#include "slang.h" 10 11namespace Slang 12{ 13 14enum class FileSystemStyle 15{ 16Load ,///< Equivalent to ISlangFileSystem 17Ext ,///< Equivalent to ISlangFileSystemExt 18Mutable ,///< Equivalent to ISlangModifyableFileSystem 19}; 20 21// Can be used for all styles of file system 22class OSFileSystem :public ISlangMutableFileSystem 23{ 24public : 25// ISlangUnknown 26// override ref counting, as DefaultFileSystem is singleton 27SLANG_IUNKNOWN_QUERY_INTERFACE 28SLANG_NO_THROW uint32_t SLANG_MCALL addRef ()SLANG_OVERRIDE {return 1 ; } 29SLANG_NO_THROW uint32_t SLANG_MCALL release ()SLANG_OVERRIDE {return 1 ; } 30 31// ISlangCastable 32virtual SLANG_NO_THROW void * SLANG_MCALL castAs (const Guid & guid )SLANG_OVERRIDE ; 33 34// ISlangFileSystem 35virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile (char const * path ,ISlangBlob ** outBlob ) 36SLANG_OVERRIDE ; 37 38// ISlangFileSystemExt 39virtual SLANG_NO_THROW SlangResult SLANG_MCALL 40getFileUniqueIdentity (const char * path ,ISlangBlob ** uniqueIdentityOut )SLANG_OVERRIDE ; 41virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath ( 42SlangPathType fromPathType , 43const char * fromPath , 44const char * path , 45ISlangBlob ** pathOut )SLANG_OVERRIDE ; 46virtual SLANG_NO_THROW SlangResult SLANG_MCALL 47getPathType (const char * path ,SlangPathType * pathTypeOut )SLANG_OVERRIDE ; 48virtual SLANG_NO_THROW SlangResult SLANG_MCALL 49getPath (PathKind pathKind ,const char * path ,ISlangBlob ** outPath )SLANG_OVERRIDE ; 50virtual SLANG_NO_THROW void SLANG_MCALL clearCache ()SLANG_OVERRIDE {} 51virtual SLANG_NO_THROW SlangResult SLANG_MCALL enumeratePathContents ( 52const char * path , 53FileSystemContentsCallBack callback , 54void * userData )SLANG_OVERRIDE ; 55virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind ()SLANG_OVERRIDE 56 { 57return OSPathKind ::Direct ; 58 } 59 60// ISlangModifyableFileSystem 61virtual SLANG_NO_THROW SlangResult SLANG_MCALL 62saveFile (const char * path ,const void * data ,size_t size )SLANG_OVERRIDE ; 63virtual SLANG_NO_THROW SlangResult SLANG_MCALL 64saveFileBlob (const char * path ,ISlangBlob * dataBlob )SLANG_OVERRIDE ; 65virtual SLANG_NO_THROW SlangResult SLANG_MCALL remove (const char * path )SLANG_OVERRIDE ; 66virtual SLANG_NO_THROW SlangResult SLANG_MCALL createDirectory (const char * path )SLANG_OVERRIDE ; 67 68/// Get a default instance 69static ISlangFileSystem * getLoadSingleton () {return & g_load ; } 70static ISlangFileSystemExt * getExtSingleton () {return & g_ext ; } 71static ISlangMutableFileSystem * getMutableSingleton () {return & g_mutable ; } 72 73private : 74/// Make so not constructible 75OSFileSystem (FileSystemStyle style ) 76 :m_style (style ) 77 { 78 } 79 80virtual ~OSFileSystem () {} 81 82ISlangUnknown * getInterface (const Guid & guid ); 83void * getObject (const Guid & guid ); 84 85FileSystemStyle m_style ; 86 87static OSFileSystem g_load ; 88static OSFileSystem g_ext ; 89static OSFileSystem g_mutable ; 90}; 91 92/* Wraps an underlying ISlangFileSystem or ISlangFileSystemExt and provides caching, 93as well as emulation of methods if only has ISlangFileSystem interface. Will query capabilities 94of the interface on the constructor. 95 96NOTE! That this behavior is the same as previously in that.... 971) calcRelativePath, just returns the path as processed by the Path:: methods 982) getUniqueIdentity behavior depends on the UniqueIdentityMode. 99*/ 100class CacheFileSystem :public ComBaseObject ,public ISlangFileSystemExt 101{ 102public : 103SLANG_CLASS_GUID (0x2f4d1d03 ,0xa0d1 ,0x434b , {0x87 ,0x7a ,0x65 ,0x5 ,0xa4 ,0xa0 ,0x9a ,0x3b }) 104 105enum class PathStyle 106 { 107Default ,///< Pass to say use the default 108Simplifiable ,///< It can be simplified by Path::Simplify 109FileSystemExt ,///< Use file system 110 }; 111 112enum UniqueIdentityMode 113 { 114Default ,///< If passed, will default to the others depending on what kind of 115///< ISlangFileSystem is passed in 116Path ,///< Just use the path as is (old style slang behavior) 117SimplifyPath ,///< Use the input path 'simplified' (ie removing . and .. aspects) 118Hash ,///< Use hashing 119SimplifyPathAndHash ,///< Tries simplifying path first, and if that doesn't work it hashes 120FileSystemExt ,///< Use the file system extended interface. 121 }; 122 123/* Cannot change order/add members without changing s_compressedResultToResult */ 124enum class CompressedResult :uint8_t 125 { 126Uninitialized ,///< Holds no value 127Ok ,///< Ok 128NotFound ,///< File not found 129CannotOpen ,///< Cannot open 130Fail ,///< Generic failure 131CountOf , 132 }; 133 134struct PathInfo 135 { 136PathInfo (const String & uniqueIdentity ) 137 :m_uniqueIdentity (uniqueIdentity ) 138 { 139m_loadFileResult = CompressedResult ::Uninitialized ; 140m_getPathTypeResult = CompressedResult ::Uninitialized ; 141m_getCanonicalPathResult = CompressedResult ::Uninitialized ; 142 143m_pathType = SLANG_PATH_TYPE_FILE ; 144 } 145 146/// Get the unique identity path as a string 147const String & getUniqueIdentity ()const {return m_uniqueIdentity ; } 148 149String m_uniqueIdentity ; 150CompressedResult m_loadFileResult ; 151CompressedResult m_getPathTypeResult ; 152CompressedResult m_getCanonicalPathResult ; 153 154SlangPathType m_pathType ; 155ComPtr < ISlangBlob > m_fileBlob ; 156String m_canonicalPath ; 157 }; 158 159Dictionary < String ,PathInfo *>& getPathMap () {return m_pathMap ; } 160Dictionary < String ,PathInfo *>& getUniqueMap () {return m_uniqueIdentityMap ; } 161 162// ISlangUnknown 163SLANG_COM_BASE_IUNKNOWN_ALL 164 165// ISlangCastable 166virtual SLANG_NO_THROW void * SLANG_MCALL castAs (const Guid & guid )SLANG_OVERRIDE ; 167 168// ISlangFileSystem 169virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile (char const * path ,ISlangBlob ** outBlob ) 170SLANG_OVERRIDE ; 171 172// ISlangFileSystemExt 173virtual SLANG_NO_THROW SlangResult SLANG_MCALL 174getFileUniqueIdentity (const char * path ,ISlangBlob ** outUniqueIdentity )SLANG_OVERRIDE ; 175virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath ( 176SlangPathType fromPathType , 177const char * fromPath , 178const char * path , 179ISlangBlob ** pathOut )SLANG_OVERRIDE ; 180virtual SLANG_NO_THROW SlangResult SLANG_MCALL 181getPathType (const char * path ,SlangPathType * outPathType )SLANG_OVERRIDE ; 182virtual SLANG_NO_THROW SlangResult SLANG_MCALL 183getPath (PathKind kind ,const char * path ,ISlangBlob ** outPath )SLANG_OVERRIDE ; 184 185virtual SLANG_NO_THROW void SLANG_MCALL clearCache ()SLANG_OVERRIDE ; 186virtual SLANG_NO_THROW SlangResult SLANG_MCALL enumeratePathContents ( 187const char * path, 188FileSystemContentsCallBack callback, 189void * userData) SLANG_OVERRIDE ; 190virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind () SLANG_OVERRIDE 191{ 192return m_osPathKind; 193} 194 195/// Get the unique identity mode 196UniqueIdentityMode getUniqueIdentityMode () const { return m_uniqueIdentityMode; } 197/// Get the path style 198PathStyle getPathStyle () const { return m_pathStyle; } 199 200/// Set the inner file system 201void setInnerFileSystem ( 202ISlangFileSystem * fileSystem, 203UniqueIdentityMode uniqueIdentityMode = UniqueIdentityMode::Default, 204PathStyle pathStyle = PathStyle::Default); 205 206/// Ctor 207explicit CacheFileSystem ( 208ISlangFileSystem * fileSystem, 209UniqueIdentityMode uniqueIdentityMode = UniqueIdentityMode::Default, 210PathStyle pathStyle = PathStyle::Default); 211/// Dtor 212virtual ~ CacheFileSystem (); 213 214static CompressedResult toCompressedResult ( Result res); 215static Result toResult ( CompressedResult compRes) 216{ 217return s_compressedResultToResult[ int (compRes)]; 218} 219static const Result s_compressedResultToResult[ int (CompressedResult::CountOf)]; 220 221protected : 222void * getInterface ( const Guid & guid); 223void * getObject ( const Guid & guid); 224 225SlangResult _getSimplifiedPath ( const char * path, ISlangBlob ** outSimplifiedPath); 226SlangResult _getCanonicalPath ( const char * path, ISlangBlob ** outCanonicalPath); 227 228/// Given a path, works out a uniqueIdentity, based on the uniqueIdentityMode. 229/// outFileContents will be set if file had to be read to produce the uniqueIdentity (ie with 230/// Hash) If the file doesn't have to be read, then outFileContents will be nullptr, even if it 231/// is backed by a file. 232SlangResult _calcUniqueIdentity ( 233const String & path, 234String & outUniqueIdentity, 235ComPtr < ISlangBlob >& outFileContents); 236 237/// For a given path gets a PathInfo. Can return nullptr, if it is not possible to create the 238/// PathInfo for some reason 239PathInfo * _resolvePathCacheInfo ( const String & path); 240/// Turns the path into a uniqueIdentity, and then tries to look up in the uniqueIdentityMap. 241PathInfo * _resolveUniqueIdentityCacheInfo ( const String & path); 242/// Will simplify the path (if possible) to lookup on the pathCache else will create on 243/// uniqueIdentityMap 244PathInfo * _resolveSimplifiedPathCacheInfo ( const String & path); 245 246SlangResult _getPathType ( PathInfo * pathInfo, const char * inPath, SlangPathType * pathTypeOut); 247 248/* TODO: This may be improved by mapping to a ISlangBlob. This makes output fast and easy, and 249if constructed as a StringBlob, we can just static_cast to get as a string to use internally, 250instead of constantly converting. It is probably the case we cannot do dynamic_cast on 251ISlangBlob if we don't know where constructed -> if outside of slang codebase doing such a cast 252can cause an exception. So we *never* want to do dynamic cast from blobs which could be created 253by external code. */ 254 255Dictionary < String, PathInfo *> m_pathMap; ///< Maps a path to a PathInfo (and unique identity) 256Dictionary < String, PathInfo *> m_uniqueIdentityMap; ///< Maps a unique identity for a file to its 257///< contents. This OWNs the PathInfo. 258 259UniqueIdentityMode m_uniqueIdentityMode; ///< Determines how the 'uniqueIdentity' is produced. 260///< Cannot be Default in usage. 261PathStyle m_pathStyle; ///< Style of paths 262 263ComPtr < ISlangFileSystem > m_fileSystem; ///< Must always be set 264ComPtr < ISlangFileSystemExt > 265m_fileSystemExt; ///< Optionally set -> if nullptr will fall back on the m_fileSystem and 266///< emulate all the other methods of ISlangFileSystemExt 267 268OSPathKind m_osPathKind = OSPathKind::None; ///< OS path kind 269}; 270 271class RelativeFileSystem : public ComBaseObject, public ISlangMutableFileSystem 272{ 273public : 274SLANG_COM_BASE_IUNKNOWN_ALL 275 276// ISlangFileSystem 277virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile ( char const * path, ISlangBlob ** outBlob) 278SLANG_OVERRIDE ; 279 280// ISlangCastable 281virtual SLANG_NO_THROW void * SLANG_MCALL castAs( const Guid & guid) SLANG_OVERRIDE ; 282 283// ISlangFileSystemExt 284virtual SLANG_NO_THROW SlangResult SLANG_MCALL 285getFileUniqueIdentity ( const char * path, ISlangBlob ** outUniqueIdentity) SLANG_OVERRIDE ; 286virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath ( 287SlangPathType fromPathType, 288const char * fromPath, 289const char * path, 290ISlangBlob ** pathOut) SLANG_OVERRIDE ; 291virtual SLANG_NO_THROW SlangResult SLANG_MCALL 292getPathType ( const char * path, SlangPathType * outPathType) SLANG_OVERRIDE ; 293virtual SLANG_NO_THROW SlangResult SLANG_MCALL 294getPath ( PathKind pathKind, const char * path, ISlangBlob ** outPath) SLANG_OVERRIDE ; 295virtual SLANG_NO_THROW void SLANG_MCALL clearCache () SLANG_OVERRIDE ; 296virtual SLANG_NO_THROW SlangResult SLANG_MCALL enumeratePathContents ( 297const char * path, 298FileSystemContentsCallBack callback, 299void * userData) SLANG_OVERRIDE ; 300virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind () SLANG_OVERRIDE 301{ 302return m_osPathKind; 303} 304 305// ISlangModifyableFileSystem 306virtual SLANG_NO_THROW SlangResult SLANG_MCALL 307saveFile ( const char * path, const void * data, size_t size) SLANG_OVERRIDE ; 308virtual SLANG_NO_THROW SlangResult SLANG_MCALL 309saveFileBlob ( const char * path, ISlangBlob * dataBlob) SLANG_OVERRIDE ; 310virtual SLANG_NO_THROW SlangResult SLANG_MCALL remove ( const char * path) SLANG_OVERRIDE ; 311virtual SLANG_NO_THROW SlangResult SLANG_MCALL createDirectory ( const char * path) SLANG_OVERRIDE ; 312 313/// stripPath will remove any path for an access, making an access always just 314/// access the *filename* from the input path, in the contained filesystem at the relative path 315RelativeFileSystem ( 316ISlangFileSystem * fileSystem, 317const String & relativePath, 318bool stripPath = false); 319 320protected : 321ISlangFileSystemExt * _getExt () 322{ 323return Index ( m_style ) >= Index (FileSystemStyle::Ext) 324? reinterpret_cast < ISlangFileSystemExt *> (m_fileSystem. get ()) 325: nullptr; 326} 327ISlangMutableFileSystem * _getMutable () 328{ 329return Index ( m_style ) >= Index (FileSystemStyle::Mutable) 330? reinterpret_cast < ISlangMutableFileSystem *> (m_fileSystem. get ()) 331: nullptr; 332} 333 334SlangResult _calcCombinedPathInner ( 335SlangPathType fromPathType, 336const char * fromPath, 337const char * path, 338ISlangBlob ** pathOut); 339 340/// Get the fixed path to the item for the backing file system. 341SlangResult _getFixedPath ( const char * path, String & outPath); 342 343SlangResult _getCanonicalPath ( const char * path, String & outPath); 344 345ISlangUnknown * getInterface ( const Guid & guid); 346void * getObject ( const Guid & guid); 347 348bool m_stripPath; ///< If set any path prior to an item will be stripped (making the directory 349///< in effect flat) 350 351FileSystemStyle m_style; 352ComPtr < ISlangFileSystem > m_fileSystem; ///< NOTE! Has to match what's in style, such style can 353///< be reached via reinterpret_cast 354 355String m_relativePath; 356OSPathKind m_osPathKind = OSPathKind::None; ///< OS path kind 357}; 358 359} // namespace Slang 360 361#endif // SLANG_FILE_SYSTEM_H_INCLUDED