mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-29 01:24:11 +01:00
[dxvk] Added COM helpers
This commit is contained in:
parent
2ee51ea4b2
commit
9b8fda512a
25
src/util/com/com_guid.cpp
Normal file
25
src/util/com/com_guid.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
#include "com_guid.h"
|
||||
|
||||
std::ostream& operator << (std::ostream& os, REFIID guid) {
|
||||
os.width(8);
|
||||
os << std::hex << guid.Data1 << '-';
|
||||
|
||||
os.width(4);
|
||||
os << std::hex << guid.Data2 << '-';
|
||||
|
||||
os.width(4);
|
||||
os << std::hex << guid.Data3 << '-';
|
||||
|
||||
os.width(2);
|
||||
os << std::hex
|
||||
<< static_cast<short>(guid.Data4[0])
|
||||
<< static_cast<short>(guid.Data4[1])
|
||||
<< '-'
|
||||
<< static_cast<short>(guid.Data4[2])
|
||||
<< static_cast<short>(guid.Data4[3])
|
||||
<< static_cast<short>(guid.Data4[4])
|
||||
<< static_cast<short>(guid.Data4[5])
|
||||
<< static_cast<short>(guid.Data4[6])
|
||||
<< static_cast<short>(guid.Data4[7]);
|
||||
return os;
|
||||
}
|
7
src/util/com/com_guid.h
Normal file
7
src/util/com/com_guid.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "com_include.h"
|
||||
|
||||
std::ostream& operator << (std::ostream& os, REFIID guid);
|
8
src/util/com/com_include.h
Normal file
8
src/util/com/com_include.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
// GCC complains about the COM interfaces
|
||||
// not having virtual destructors
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
40
src/util/com/com_object.h
Normal file
40
src/util/com/com_object.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "com_include.h"
|
||||
|
||||
#define COM_QUERY_IFACE(riid, ppvObject, Iface) \
|
||||
if (riid == __uuidof(Iface)) { \
|
||||
this->AddRef(); \
|
||||
*ppvObject = static_cast<Iface*>(this); \
|
||||
return S_OK; \
|
||||
}
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
template<typename... Base>
|
||||
class ComObject : public Base... {
|
||||
|
||||
public:
|
||||
|
||||
virtual ~ComObject() { }
|
||||
|
||||
ULONG AddRef() final {
|
||||
return ++m_refCount;
|
||||
}
|
||||
|
||||
ULONG Release() final {
|
||||
ULONG refCount = --m_refCount;
|
||||
if (refCount == 0)
|
||||
delete this;
|
||||
return refCount;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::atomic<ULONG> m_refCount = { 0ul };
|
||||
|
||||
};
|
||||
|
||||
}
|
101
src/util/com/com_pointer.h
Normal file
101
src/util/com/com_pointer.h
Normal file
@ -0,0 +1,101 @@
|
||||
#pragma once
|
||||
|
||||
#include "com_include.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief COM pointer
|
||||
*
|
||||
* Implements automatic reference
|
||||
* counting for COM objects.
|
||||
*/
|
||||
template<typename T>
|
||||
class Com {
|
||||
|
||||
public:
|
||||
|
||||
Com() { }
|
||||
Com(std::nullptr_t) { }
|
||||
Com(T* object)
|
||||
: m_ptr(object) {
|
||||
this->incRef();
|
||||
}
|
||||
|
||||
Com(const Com& other)
|
||||
: m_ptr(other.m_ptr) {
|
||||
this->incRef();
|
||||
}
|
||||
|
||||
Com(Com&& other)
|
||||
: m_ptr(other.m_ptr) {
|
||||
other.m_ptr = nullptr;
|
||||
}
|
||||
|
||||
Com& operator = (const Com& other) {
|
||||
other.incRef();
|
||||
this->decRef();
|
||||
m_ptr = other.m_ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Com& operator = (Com&& other) {
|
||||
this->decRef();
|
||||
this->m_ptr = other.m_ptr;
|
||||
other.m_ptr = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Com& operator = (std::nullptr_t) {
|
||||
this->decRef();
|
||||
m_ptr = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Com() {
|
||||
this->decRef();
|
||||
}
|
||||
|
||||
T* operator -> () const {
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
T** operator & () { return &m_ptr; }
|
||||
T* const* operator & () const { return &m_ptr; }
|
||||
|
||||
bool operator == (std::nullptr_t) const { return m_ptr == nullptr; }
|
||||
bool operator != (std::nullptr_t) const { return m_ptr != nullptr; }
|
||||
|
||||
T* ref() const {
|
||||
this->incRef();
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
T* ptr() const {
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T* m_ptr = nullptr;
|
||||
|
||||
void incRef() const {
|
||||
if (m_ptr != nullptr)
|
||||
m_ptr->AddRef();
|
||||
}
|
||||
|
||||
void decRef() const {
|
||||
if (m_ptr != nullptr)
|
||||
m_ptr->Release();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T* ref(T* object) {
|
||||
if (object != nullptr)
|
||||
object->AddRef();
|
||||
return object;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
util_src = files([
|
||||
'com/com_guid.cpp',
|
||||
|
||||
'log/log.cpp',
|
||||
'log/log_debug.cpp',
|
||||
])
|
||||
|
Loading…
Reference in New Issue
Block a user