yum-mirror/slang

Making it easier to work with shaders

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

Ellie Hermaszewskaformatf65d756bf

master
6.0 KiB265 linesraw
1#include "slang-blob.h"
2
3namespace Slang
4{
5
6/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! BlobBase !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
7
8ISlangUnknown* BlobBase::getInterface(const Guid& guid)
9{
10    if (guid == ISlangUnknown::getTypeGuid() || guid == ISlangBlob::getTypeGuid())
11    {
12        return static_cast<ISlangBlob*>(this);
13    }
14    if (guid == ICastable::getTypeGuid())
15    {
16        return static_cast<ICastable*>(this);
17    }
18    return nullptr;
19}
20
21void* BlobBase::getObject(const Guid& guid)
22{
23    SLANG_UNUSED(guid);
24    return nullptr;
25}
26
27void* BlobBase::castAs(const SlangUUID& guid)
28{
29    if (auto intf = getInterface(guid))
30    {
31        return intf;
32    }
33    return getObject(guid);
34}
35
36/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StringBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
37
38void StringBlob::_setUniqueRep(StringRepresentation* uniqueRep)
39{
40    SLANG_ASSERT(uniqueRep == nullptr || uniqueRep->isUniquelyReferenced());
41
42    m_uniqueRep = uniqueRep;
43
44    m_slice = uniqueRep ? UnownedTerminatedStringSlice(uniqueRep->getData(), uniqueRep->getLength())
45                        : UnownedTerminatedStringSlice();
46}
47
48/* static */ StringRepresentation* StringBlob::_createUniqueCopy(StringRepresentation* rep)
49{
50    if (rep)
51    {
52        // If the length is 0, we can just init as empty
53        auto length = rep->getLength();
54        if (length == 0)
55        {
56            return nullptr;
57        }
58        else
59        {
60            const UnownedStringSlice slice(rep->getData(), length);
61            return StringRepresentation::createWithReference(slice);
62        }
63    }
64    return nullptr;
65}
66
67void StringBlob::_setWithCopy(StringRepresentation* rep)
68{
69    _setUniqueRep(_createUniqueCopy(rep));
70}
71
72void StringBlob::_setWithMove(StringRepresentation* rep)
73{
74    if (rep && !rep->isUniquelyReferenced())
75    {
76        _setUniqueRep(_createUniqueCopy(rep));
77        // We need to release a ref as rep is passed in with the 'current' ref count
78        rep->releaseReference();
79    }
80    else
81    {
82        _setUniqueRep(rep);
83    }
84}
85
86/* static */ ComPtr<ISlangBlob> StringBlob::create(const UnownedStringSlice& slice)
87{
88    StringRepresentation* rep = nullptr;
89    if (slice.getLength())
90    {
91        rep = StringRepresentation::createWithReference(slice);
92    }
93
94    auto blob = new StringBlob;
95
96    // rep must be unique at this point
97    blob->_setUniqueRep(rep);
98    return ComPtr<ISlangBlob>(blob);
99}
100
101/* static */ ComPtr<ISlangBlob> StringBlob::create(const String& in)
102{
103    auto blob = new StringBlob;
104    blob->_setWithCopy(in.getStringRepresentation());
105    return ComPtr<ISlangBlob>(blob);
106}
107
108/* static */ ComPtr<ISlangBlob> StringBlob::moveCreate(String& in)
109{
110    auto blob = new StringBlob;
111    blob->_setWithMove(in.detachStringRepresentation());
112    return ComPtr<ISlangBlob>(blob);
113}
114
115/* static */ ComPtr<ISlangBlob> StringBlob::moveCreate(String&& in)
116{
117    auto blob = new StringBlob;
118    blob->_setWithMove(in.detachStringRepresentation());
119    return ComPtr<ISlangBlob>(blob);
120}
121
122StringBlob::~StringBlob()
123{
124    if (m_uniqueRep)
125    {
126        delete m_uniqueRep;
127    }
128}
129void* StringBlob::castAs(const SlangUUID& guid)
130{
131    if (auto intf = getInterface(guid))
132    {
133        return intf;
134    }
135    return getObject(guid);
136}
137
138void* StringBlob::getObject(const Guid& guid)
139{
140    // Can allow accessing the contained String
141    if (guid == getTypeGuid())
142    {
143        return this;
144    }
145    // Can always be accessed as terminated char*
146    if (guid == SlangTerminatedChars::getTypeGuid())
147    {
148        return const_cast<char*>(m_slice.begin());
149    }
150    return nullptr;
151}
152
153/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RawBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
154
155void* RawBlob::castAs(const SlangUUID& guid)
156{
157    if (auto intf = getInterface(guid))
158    {
159        return intf;
160    }
161    return getObject(guid);
162}
163
164void* RawBlob::getObject(const Guid& guid)
165{
166    // If the data has 0 termination, we can return the pointer
167    if (guid == SlangTerminatedChars::getTypeGuid() && m_data.isTerminated())
168    {
169        return (char*)m_data.getData();
170    }
171    return nullptr;
172}
173
174/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ScopeBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
175
176void* ScopeBlob::castAs(const SlangUUID& guid)
177{
178    if (auto intf = getInterface(guid))
179    {
180        return intf;
181    }
182    if (auto obj = getObject(guid))
183    {
184        return obj;
185    }
186
187    // If the contained thing is castable, ask it
188    if (m_castable)
189    {
190        return m_castable->castAs(guid);
191    }
192
193    return nullptr;
194}
195
196/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ListBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
197
198void* ListBlob::castAs(const SlangUUID& guid)
199{
200    if (auto intf = getInterface(guid))
201    {
202        return intf;
203    }
204    return getObject(guid);
205}
206
207void* ListBlob::getObject(const Guid& guid)
208{
209    // If the data is terminated return the pointer
210    if (guid == SlangTerminatedChars::getTypeGuid())
211    {
212        const auto count = m_data.getCount();
213        if (m_data.getCapacity() > count)
214        {
215            auto buf = m_data.getBuffer();
216            if (buf[count] == 0)
217            {
218                return (char*)buf;
219            }
220        }
221    }
222    return nullptr;
223}
224
225/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StaticBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
226
227SlangResult StaticBlob::queryInterface(SlangUUID const& guid, void** outObject)
228{
229    if (auto intf = getInterface(guid))
230    {
231        *outObject = intf;
232        return SLANG_OK;
233    }
234    return SLANG_E_NO_INTERFACE;
235}
236
237void* StaticBlob::castAs(const SlangUUID& guid)
238{
239    if (auto intf = getInterface(guid))
240    {
241        return intf;
242    }
243    return getObject(guid);
244}
245
246ISlangUnknown* StaticBlob::getInterface(const Guid& guid)
247{
248    if (guid == ISlangUnknown::getTypeGuid() || guid == ISlangBlob::getTypeGuid())
249    {
250        return static_cast<ISlangBlob*>(this);
251    }
252    if (guid == ICastable::getTypeGuid())
253    {
254        return static_cast<ICastable*>(this);
255    }
256    return nullptr;
257}
258
259void* StaticBlob::getObject(const Guid& guid)
260{
261    SLANG_UNUSED(guid);
262    return nullptr;
263}
264
265} // namespace Slang