#pragma once #include "miniwin/d3drm.h" #include #include template struct Direct3DRMObjectBaseImpl : public T { Direct3DRMObjectBaseImpl() : T() {} Direct3DRMObjectBaseImpl(const Direct3DRMObjectBaseImpl& other) : m_appData(other.m_appData), T(other) { if (other.m_name) { m_name = SDL_strdup(other.m_name); } } ULONG Release() override { if (T::m_refCount == 1) { for (auto it = m_callbacks.cbegin(); it != m_callbacks.cend(); it++) { it->first(this, it->second); } m_callbacks.clear(); } SDL_free(m_name); return this->T::Release(); } HRESULT AddDestroyCallback(D3DRMOBJECTCALLBACK callback, void* arg) override { m_callbacks.push_back(std::make_pair(callback, arg)); return D3DRM_OK; } HRESULT DeleteDestroyCallback(D3DRMOBJECTCALLBACK callback, void* arg) override { for (auto it = m_callbacks.cbegin(); it != m_callbacks.cend(); it++) { if (it->first == callback && it->second == arg) { m_callbacks.erase(it); return D3DRM_OK; } } return D3DRMERR_NOTFOUND; } HRESULT SetAppData(LPD3DRM_APPDATA appData) override { m_appData = appData; return D3DRM_OK; } LPVOID GetAppData() override { return m_appData; } HRESULT SetName(const char* name) override { SDL_free(m_name); m_name = NULL; if (name) { m_name = SDL_strdup(name); } return D3DRM_OK; } HRESULT GetName(DWORD* size, char* name) override { if (!size) { return DDERR_INVALIDPARAMS; } const char* s = m_name ? m_name : ""; size_t l = SDL_strlen(s); if (name) { SDL_strlcpy(name, s, *size); } else { *size = l + 1; } return D3DRM_OK; } private: std::vector> m_callbacks; LPD3DRM_APPDATA m_appData = nullptr; char* m_name = nullptr; };