summaryrefslogtreecommitdiff
path: root/source/core/slang-shared-library.h
blob: 675ee5caee6a1446fc4de3f629287828dad13b7f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#ifndef SLANG_CORE_SHARED_LIBRARY_H
#define SLANG_CORE_SHARED_LIBRARY_H

#include "../../slang.h"
#include "../../slang-com-helper.h"
#include "../../slang-com-ptr.h"

#include "../core/slang-io.h"
#include "../core/slang-platform.h"
#include "../core/slang-common.h"
#include "../core/slang-dictionary.h"

namespace Slang
{

/* NOTE! Do not change this enum without making the appropriate changes to DefaultSharedLibraryLoader::s_libraryNames */
enum class SharedLibraryType
{
    Unknown,            ///< Unknown compiler
    Dxc,                ///< Dxc compiler
    Fxc,                ///< Fxc compiler
    Glslang,            ///< Slang specific glslang compiler
    Dxil,               ///< Dxil is used with dxc
    CountOf,
};

class DefaultSharedLibraryLoader : public ISlangSharedLibraryLoader
{
public:

    // ISlangUnknown 
    // override ref counting, as DefaultSharedLibraryLoader 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; } 

    // ISlangSharedLibraryLoader
    virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadSharedLibrary(const char* path, 
        ISlangSharedLibrary** sharedLibraryOut) SLANG_OVERRIDE;

        /// Get the singleton
    static DefaultSharedLibraryLoader* getSingleton() { return &s_singleton; }

        /// Get the type from the name
    static SharedLibraryType getSharedLibraryTypeFromName(const UnownedStringSlice& name);

        /// Get the name from the type, or nullptr if not known
    static const char* getSharedLibraryNameFromType(SharedLibraryType type) { return s_libraryNames[int(type)]; }

        /// Make a shared library to it's name
    static const char* s_libraryNames[int(SharedLibraryType::CountOf)];

private:
        /// Make so not constructible
    DefaultSharedLibraryLoader() {}
    virtual ~DefaultSharedLibraryLoader() {}

    ISlangUnknown* getInterface(const Guid& guid);

    static DefaultSharedLibraryLoader s_singleton;
};

class DefaultSharedLibrary : public ISlangSharedLibrary, public RefObject
{
    public:
    // ISlangUnknown 
    SLANG_REF_OBJECT_IUNKNOWN_ALL

    // ISlangSharedLibrary
    virtual SLANG_NO_THROW SlangFuncPtr SLANG_MCALL findFuncByName(char const* name) SLANG_OVERRIDE;

        /// Ctor.
    DefaultSharedLibrary(const SharedLibrary::Handle sharedLibraryHandle):
        m_sharedLibraryHandle(sharedLibraryHandle)
    {
        SLANG_ASSERT(sharedLibraryHandle);
    }

        /// Need virtual dtor to keep delete this happy
    virtual ~DefaultSharedLibrary();

    protected:
    ISlangUnknown* getInterface(const Guid& guid);

    SharedLibrary::Handle m_sharedLibraryHandle = nullptr;
};

class TemporarySharedLibrary : public DefaultSharedLibrary
{
public:
    typedef DefaultSharedLibrary Super;

        /// Get the path to the shared library
    const String& getPath() const { return m_path; }

        /// Ctor
    TemporarySharedLibrary(const SharedLibrary::Handle sharedLibraryHandle, const String& path):
        Super(sharedLibraryHandle),
        m_path(path)
    {
    }

    virtual ~TemporarySharedLibrary();

        /// Any files specified in this set will be deleted on exit
    TemporaryFileSet m_temporaryFileSet;

protected:
    String m_path;
};

class ConfigurableSharedLibraryLoader: public ISlangSharedLibraryLoader, public RefObject
{
public:
    typedef Result (*Func)(const char* pathIn, const String& entryString, SharedLibrary::Handle& handleOut);

    // IUnknown
    SLANG_REF_OBJECT_IUNKNOWN_ALL

    // ISlangSharedLibraryLoader
    virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadSharedLibrary(const char* path, ISlangSharedLibrary** sharedLibraryOut) SLANG_OVERRIDE;

        /// Function to replace the the path with entryString
    static Result replace(const char* pathIn, const String& entryString, SharedLibrary::Handle& handleOut);
        /// Function to change the path using the entryString
    static Result changePath(const char* pathIn, const String& entryString, SharedLibrary::Handle& handleOut);

    void addEntry(const String& libName, Func func, const String& entryString) { m_entryMap.Add(libName, Entry{ func, entryString} ); }
    void addEntry(SharedLibraryType libType, Func func, const String& entryString) { m_entryMap.Add(DefaultSharedLibraryLoader::getSharedLibraryNameFromType(libType), Entry { func, entryString} ); }

    virtual ~ConfigurableSharedLibraryLoader() {}
    protected:

    struct Entry
    {
        Func func;
        String entryString;
    };

    ISlangUnknown* getInterface(const Guid& guid);

    Dictionary<String, Entry> m_entryMap;
};

}

#endif // SLANG_SHARED_LIBRARY_H_INCLUDED