From f9710d50bc675ddba51cc6d94b125ba1549708a8 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Wed, 17 Oct 2018 11:57:33 -0400 Subject: IncludeFileSystem -> DefaultFileSystem (#677) Improvements in 'singleton'ness of DefaultFileSystem Made WrapFileSystem a stand alone type - to remove 'odd' aspects of deriving from DefaultFileSystem (such as inheriting getSingleton method/fixing ref counting) Simplified CompileRequest::loadFile - becauce fileSystemExt is always available. --- source/slang/default-file-system.cpp | 110 +++++++++++++++++++++++++++++++++++ source/slang/default-file-system.h | 93 +++++++++++++++++++++++++++++ source/slang/include-file-system.cpp | 101 -------------------------------- source/slang/include-file-system.h | 81 -------------------------- source/slang/slang.cpp | 41 ++----------- source/slang/slang.vcxproj | 4 +- source/slang/slang.vcxproj.filters | 12 ++-- 7 files changed, 215 insertions(+), 227 deletions(-) create mode 100644 source/slang/default-file-system.cpp create mode 100644 source/slang/default-file-system.h delete mode 100644 source/slang/include-file-system.cpp delete mode 100644 source/slang/include-file-system.h (limited to 'source') diff --git a/source/slang/default-file-system.cpp b/source/slang/default-file-system.cpp new file mode 100644 index 000000000..be171d37c --- /dev/null +++ b/source/slang/default-file-system.cpp @@ -0,0 +1,110 @@ +#include "default-file-system.h" + +#include "../../slang-com-ptr.h" +#include "../core/slang-io.h" +#include "compiler.h" + +namespace Slang +{ + +// Allocate static const storage for the various interface IDs that the Slang API needs to expose +static const Guid IID_ISlangUnknown = SLANG_UUID_ISlangUnknown; +static const Guid IID_ISlangFileSystem = SLANG_UUID_ISlangFileSystem; +static const Guid IID_ISlangFileSystemExt = SLANG_UUID_ISlangFileSystemExt; + +/* !!!!!!!!!!!!!!!!!!!!!!!!!! IncludeFileSystem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ + +/* static */DefaultFileSystem DefaultFileSystem::s_singleton; + +ISlangUnknown* DefaultFileSystem::getInterface(const Guid& guid) +{ + return (guid == IID_ISlangUnknown || guid == IID_ISlangFileSystem || guid == IID_ISlangFileSystemExt) ? static_cast(this) : nullptr; +} + +SlangResult DefaultFileSystem::getCanoncialPath(const char* path, ISlangBlob** canonicalPathOut) +{ + String canonicalPath; + SLANG_RETURN_ON_FAIL(Path::GetCanonical(path, canonicalPath)); + + *canonicalPathOut = createStringBlob(canonicalPath).detach(); + return SLANG_OK; +} + +SlangResult DefaultFileSystem::calcRelativePath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) +{ + String relPath; + switch (fromPathType) + { + case SLANG_PATH_TYPE_FILE: + { + relPath = Path::Combine(Path::GetDirectoryName(fromPath), path); + break; + } + case SLANG_PATH_TYPE_DIRECTORY: + { + relPath = Path::Combine(fromPath, path); + break; + } + } + + *pathOut = createStringBlob(relPath).detach(); + return SLANG_OK; +} + +SlangResult DefaultFileSystem::loadFile(char const* path, ISlangBlob** outBlob) +{ + // Default implementation that uses the `core` + // libraries facilities for talking to the OS filesystem. + // + // TODO: we might want to conditionally compile these in, so that + // a user could create a build of Slang that doesn't include any OS + // filesystem calls. + + if (!File::Exists(path)) + { + return SLANG_E_NOT_FOUND; + } + + try + { + String sourceString = File::ReadAllText(path); + ComPtr sourceBlob = createStringBlob(sourceString); + *outBlob = sourceBlob.detach(); + return SLANG_OK; + } + catch (...) + { + } + return SLANG_E_CANNOT_OPEN; +} + +/* !!!!!!!!!!!!!!!!!!!!!!!!!! WrapFileSystem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ + +ISlangUnknown* WrapFileSystem::getInterface(const Guid& guid) +{ + return (guid == IID_ISlangUnknown || guid == IID_ISlangFileSystem || guid == IID_ISlangFileSystemExt) ? static_cast(this) : nullptr; +} + +SlangResult WrapFileSystem::loadFile(char const* path, ISlangBlob** outBlob) +{ + // Used the wrapped file system to do the loading + return m_fileSystem->loadFile(path, outBlob); +} + +SlangResult WrapFileSystem::getCanoncialPath(const char* path, ISlangBlob** canonicalPathOut) +{ + // This isn't a very good 'canonical path' because the same file might be referenced + // multiple ways - for example by using relative paths. + // But it's simple and matches slangs previous behavior. + String canonicalPath(path); + *canonicalPathOut = createStringBlob(canonicalPath).detach(); + return SLANG_OK; +} + +SlangResult WrapFileSystem::calcRelativePath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) +{ + // Just defer to the default implementation + return DefaultFileSystem::getSingleton()->calcRelativePath(fromPathType, fromPath, path, pathOut); +} + +} \ No newline at end of file diff --git a/source/slang/default-file-system.h b/source/slang/default-file-system.h new file mode 100644 index 000000000..62d7cbfc5 --- /dev/null +++ b/source/slang/default-file-system.h @@ -0,0 +1,93 @@ +#ifndef SLANG_DEFAULT_FILE_SYSTEM_H_INCLUDED +#define SLANG_DEFAULT_FILE_SYSTEM_H_INCLUDED + +#include "../../slang.h" +#include "../../slang-com-helper.h" +#include "../../slang-com-ptr.h" + +namespace Slang +{ + +class DefaultFileSystem : public ISlangFileSystemExt +{ +public: + // ISlangUnknown + // override ref counting, as DefaultFileSystem is singleton + SLANG_IUNKNOWN_QUERY_INTERFACE + SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; } + SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; } + + // ISlangFileSystem + virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile( + char const* path, + ISlangBlob** outBlob) SLANG_OVERRIDE; + + // ISlangFileSystemExt + virtual SLANG_NO_THROW SlangResult SLANG_MCALL getCanoncialPath( + const char* path, + ISlangBlob** canonicalPathOut) SLANG_OVERRIDE; + + virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcRelativePath( + SlangPathType fromPathType, + const char* fromPath, + const char* path, + ISlangBlob** pathOut) SLANG_OVERRIDE; + + /// Get a default instance + static ISlangFileSystemExt* getSingleton() { return &s_singleton; } + +private: + /// Make so not constructable + DefaultFileSystem() {} + + ISlangUnknown* getInterface(const Guid& guid); + + static DefaultFileSystem s_singleton; +}; + +/* Wraps an ISlangFileSystem, and provides the extra methods required to make a ISlangFileSystemExt +interface, deferring to the contained file system to do reading. + +NOTE! That this behavior is the same as previously in that.... +1) calcRelativePath, just returns the path as processed by the Path:: methods +2) getCanonicalPath, just returns the input path as the 'canonical' path. This will be wrong with a file multiply referenced through paths with .. and or . but +doing it this way means it works as before and requires no new functions. +*/ +class WrapFileSystem : public ISlangFileSystemExt +{ +public: + // ISlangUnknown + SLANG_IUNKNOWN_ALL + + // ISlangFileSystem + virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile( + char const* path, + ISlangBlob** outBlob) SLANG_OVERRIDE; + + // ISlangFileSystemExt + virtual SLANG_NO_THROW SlangResult SLANG_MCALL getCanoncialPath( + const char* path, + ISlangBlob** canonicalPathOut) SLANG_OVERRIDE; + + virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcRelativePath( + SlangPathType fromPathType, + const char* fromPath, + const char* path, + ISlangBlob** pathOut) SLANG_OVERRIDE; + + /// Ctor + WrapFileSystem(ISlangFileSystem* fileSystem): + m_fileSystem(fileSystem) + { + } + +protected: + ISlangUnknown* getInterface(const Guid& guid); + + ComPtr m_fileSystem; ///< The wrapped file system + uint32_t m_refCount = 0; +}; + +} + +#endif \ No newline at end of file diff --git a/source/slang/include-file-system.cpp b/source/slang/include-file-system.cpp deleted file mode 100644 index d2c1670fe..000000000 --- a/source/slang/include-file-system.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "include-file-system.h" - -#include "../../slang-com-ptr.h" -#include "../core/slang-io.h" -#include "compiler.h" - -namespace Slang -{ - -// Allocate static const storage for the various interface IDs that the Slang API needs to expose -static const Guid IID_ISlangUnknown = SLANG_UUID_ISlangUnknown; -static const Guid IID_ISlangFileSystem = SLANG_UUID_ISlangFileSystem; -static const Guid IID_ISlangFileSystemExt = SLANG_UUID_ISlangFileSystemExt; - -/* !!!!!!!!!!!!!!!!!!!!!!!!!! IncludeFileSystem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ - -/* static */ISlangFileSystemExt* IncludeFileSystem::getDefault() -{ - static IncludeFileSystem s_includeFileSystem; - s_includeFileSystem.ensureRef(); - return &s_includeFileSystem; -} - -ISlangUnknown* IncludeFileSystem::getInterface(const Guid& guid) -{ - return (guid == IID_ISlangUnknown || guid == IID_ISlangFileSystem || guid == IID_ISlangFileSystemExt) ? static_cast(this) : nullptr; -} - -SlangResult IncludeFileSystem::getCanoncialPath(const char* path, ISlangBlob** canonicalPathOut) -{ - String canonicalPath; - SLANG_RETURN_ON_FAIL(Path::GetCanonical(path, canonicalPath)); - - *canonicalPathOut = createStringBlob(canonicalPath).detach(); - return SLANG_OK; -} - -SlangResult IncludeFileSystem::calcRelativePath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) -{ - String relPath; - switch (fromPathType) - { - case SLANG_PATH_TYPE_FILE: - { - relPath = Path::Combine(Path::GetDirectoryName(fromPath), path); - break; - } - case SLANG_PATH_TYPE_DIRECTORY: - { - relPath = Path::Combine(fromPath, path); - break; - } - } - - *pathOut = createStringBlob(relPath).detach(); - return SLANG_OK; -} - -SlangResult SLANG_MCALL IncludeFileSystem::loadFile(char const* path, ISlangBlob** outBlob) -{ - // Otherwise, fall back to a default implementation that uses the `core` - // libraries facilities for talking to the OS filesystem. - // - // TODO: we might want to conditionally compile these in, so that - // a user could create a build of Slang that doesn't include any OS - // filesystem calls. - // - - if (!File::Exists(path)) - { - return SLANG_E_NOT_FOUND; - } - - try - { - String sourceString = File::ReadAllText(path); - ComPtr sourceBlob = createStringBlob(sourceString); - *outBlob = sourceBlob.detach(); - return SLANG_OK; - } - catch (...) - { - } - return SLANG_E_CANNOT_OPEN; -} - -/* !!!!!!!!!!!!!!!!!!!!!!!!!! WrapFileSystem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ - -SlangResult SLANG_MCALL WrapFileSystem::loadFile(char const* path, ISlangBlob** outBlob) -{ - return m_fileSystem->loadFile(path, outBlob); -} - -SlangResult WrapFileSystem::getCanoncialPath(const char* path, ISlangBlob** canonicalPathOut) -{ - String canonicalPath(path); - *canonicalPathOut = createStringBlob(canonicalPath).detach(); - return SLANG_OK; -} - -} \ No newline at end of file diff --git a/source/slang/include-file-system.h b/source/slang/include-file-system.h deleted file mode 100644 index 4b34c2a0f..000000000 --- a/source/slang/include-file-system.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef SLANG_INCLUDE_FILE_SYSTEM_H_INCLUDED -#define SLANG_INCLUDE_FILE_SYSTEM_H_INCLUDED - -#include "../../slang.h" -#include "../../slang-com-helper.h" -#include "../../slang-com-ptr.h" - -namespace Slang -{ - -class IncludeFileSystem : public ISlangFileSystemExt -{ -public: - // ISlangUnknown - SLANG_IUNKNOWN_ALL - - // ISlangFileSystem - virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile( - char const* path, - ISlangBlob** outBlob) SLANG_OVERRIDE; - - // ISlangFileSystemExt - virtual SLANG_NO_THROW SlangResult SLANG_MCALL getCanoncialPath( - const char* path, - ISlangBlob** canonicalPathOut) SLANG_OVERRIDE; - - virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcRelativePath( - SlangPathType fromPathType, - const char* fromPath, - const char* path, - ISlangBlob** pathOut) SLANG_OVERRIDE; - - /// Get a default instance - static ISlangFileSystemExt* getDefault(); - -protected: - - /// If no ref, add one to the ref - void ensureRef() { m_refCount += (m_refCount == 0); } - - ISlangUnknown* getInterface(const Guid& guid); - uint32_t m_refCount = 0; -}; - -/* Wraps an ISlangFileSystem, and provides the extra methods required to make a ISlangFileSystemExt -interface, deferring to the contained file system to do reading. - -NOTE! That this behavior is the same as previously in that.... -1) getRelativePath, just returns the path as processed by the Path:: methods -2) getCanonicalPath, just returns the input path as the 'canonical' path. This will be wrong with a file multiply referenced through paths with .. and or . but -doing it this way means it works as before and requires no new functions. -*/ -class WrapFileSystem : public IncludeFileSystem -{ -public: - // So we don't need virtual dtor - SLANG_IUNKNOWN_RELEASE - - // ISlangFileSystem - virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile( - char const* path, - ISlangBlob** outBlob) SLANG_OVERRIDE; - - // ISlangFileSystemExt - virtual SLANG_NO_THROW SlangResult SLANG_MCALL getCanoncialPath( - const char* path, - ISlangBlob** canonicalPathOut) SLANG_OVERRIDE; - - /// Ctor - WrapFileSystem(ISlangFileSystem* fileSystem): - m_fileSystem(fileSystem) - { - } - -protected: - ComPtr m_fileSystem; ///< The wrapped file system -}; - -} - -#endif \ No newline at end of file diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 908bee283..5461afbf7 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -9,7 +9,7 @@ #include "syntax-visitors.h" #include "../slang/type-layout.h" -#include "include-file-system.h" +#include "default-file-system.h" #include "ir-serialize.h" @@ -316,7 +316,7 @@ CompileRequest::CompileRequest(Session* session) // Set up the default file system SLANG_ASSERT(fileSystem == nullptr); - fileSystemExt = IncludeFileSystem::getDefault(); + fileSystemExt = DefaultFileSystem::getSingleton(); } CompileRequest::~CompileRequest() @@ -407,42 +407,9 @@ ComPtr createRawBlob(void const* inData, size_t size) SlangResult CompileRequest::loadFile(String const& path, ISlangBlob** outBlob) { - // If there is a used-defined filesystem, then use that to load files. - // - if(fileSystem) - { - return fileSystem->loadFile(path.Buffer(), outBlob); - } - - // Otherwise, fall back to a default implementation that uses the `core` - // libraries facilities for talking to the OS filesystem. - // - // TODO: we might want to conditionally compile these in, so that - // a user could create a build of Slang that doesn't include any OS - // filesystem calls. - // - - if (!File::Exists(path)) - { - return SLANG_FAIL; - } - - try - { - String sourceString = File::ReadAllText(path); - ComPtr sourceBlob = createStringBlob(sourceString); - *outBlob = sourceBlob.detach(); - - return SLANG_OK; - } - catch(...) - { - } - return SLANG_FAIL; - + return fileSystemExt->loadFile(path.Buffer(), outBlob); } - RefPtr CompileRequest::parseTypeString(TranslationUnitRequest * translationUnit, String typeStr, RefPtr scope) { // Create a SourceManager on the stack, so any allocations for 'SourceFile'/'SourceView' etc will be cleaned up @@ -1214,7 +1181,7 @@ SLANG_API void spSetFileSystem( // Set up fileSystemExt appropriately if (fileSystem == nullptr) { - req->fileSystemExt = Slang::IncludeFileSystem::getDefault(); + req->fileSystemExt = Slang::DefaultFileSystem::getSingleton(); } else { diff --git a/source/slang/slang.vcxproj b/source/slang/slang.vcxproj index 970f4f5fb..b899506b4 100644 --- a/source/slang/slang.vcxproj +++ b/source/slang/slang.vcxproj @@ -175,13 +175,13 @@ + - @@ -228,10 +228,10 @@ + - diff --git a/source/slang/slang.vcxproj.filters b/source/slang/slang.vcxproj.filters index e8c86a372..6b51e16c8 100644 --- a/source/slang/slang.vcxproj.filters +++ b/source/slang/slang.vcxproj.filters @@ -24,6 +24,9 @@ Header Files + + Header Files + Header Files @@ -42,9 +45,6 @@ Header Files - - Header Files - Header Files @@ -179,6 +179,9 @@ Source Files + + Source Files + Source Files @@ -188,9 +191,6 @@ Source Files - - Source Files - Source Files -- cgit v1.2.3