summaryrefslogtreecommitdiffstats
path: root/source/core/slang-castable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/core/slang-castable.cpp')
-rw-r--r--source/core/slang-castable.cpp70
1 files changed, 70 insertions, 0 deletions
diff --git a/source/core/slang-castable.cpp b/source/core/slang-castable.cpp
new file mode 100644
index 000000000..f3c6541dd
--- /dev/null
+++ b/source/core/slang-castable.cpp
@@ -0,0 +1,70 @@
+// slang-castable.cpp
+#include "slang-castable.h"
+
+namespace Slang {
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CastableUtil !!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+/* static */ComPtr<ICastable> CastableUtil::getCastable(ISlangUnknown* unk)
+{
+ SLANG_ASSERT(unk);
+ ComPtr<ICastable> castable;
+ if (SLANG_SUCCEEDED(unk->queryInterface(SLANG_IID_PPV_ARGS(castable.writeRef()))))
+ {
+ SLANG_ASSERT(castable);
+ }
+ else
+ {
+ castable = new UnknownCastableAdapter(unk);
+ }
+ return castable;
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! UnknownCastableAdapter !!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+void* UnknownCastableAdapter::castAs(const Guid& guid)
+{
+ if (auto intf = getInterface(guid))
+ {
+ return intf;
+ }
+ if (auto obj = getObject(guid))
+ {
+ return obj;
+ }
+
+ if (m_found && guid == m_foundGuid)
+ {
+ return m_found;
+ }
+
+ ComPtr<ISlangUnknown> cast;
+ if (SLANG_SUCCEEDED(m_contained->queryInterface(guid, (void**)cast.writeRef())) && cast)
+ {
+ // Save the interface in the cache
+ m_found = cast;
+ m_foundGuid = guid;
+
+ return cast;
+ }
+ return nullptr;
+}
+
+void* UnknownCastableAdapter::getInterface(const Guid& guid)
+{
+ if (guid == ISlangUnknown::getTypeGuid() ||
+ guid == ICastable::getTypeGuid() ||
+ guid == IUnknownCastableAdapter::getTypeGuid())
+ {
+ return static_cast<IUnknownCastableAdapter*>(this);
+ }
+ return nullptr;
+}
+
+void* UnknownCastableAdapter::getObject(const Guid& guid)
+{
+ SLANG_UNUSED(guid);
+ return nullptr;
+}
+
+} // namespace Slang