#pragma once #include #include template using ComPtr = Microsoft::WRL::ComPtr; // {C942AA9B-C576-4D3F-A54F-B135B500E611} inline const GUID IID_IComponentContainer = { 0xc942aa9b, 0xc576, 0x4d3f, 0xa5, 0x4f, 0xb1, 0x35, 0xb5, 0x0, 0xe6, 0x11 }; template struct TypedGet { template ComPtr Get() { ComPtr temp; ComPtr pComponent = ((T*)this)->Get(__uuidof(TGet)); if (pComponent) { HRESULT hr = pComponent.As(&temp); if (FAILED(hr)) { if (hr == E_NOINTERFACE) { throw std::invalid_argument("The interface is not supported."); } throw std::invalid_argument(fmt::format("Unknown exception {0:x} querying interface.", hr)); } pComponent.Detach(); return temp; } return ComPtr(); // Null } }; /// /// Container for game components. /// Facilitates resource acquisition across module boundaries, and interop with .NET code. /// struct IComponentContainer : public TypedGet { virtual ~IComponentContainer() { } virtual void Add(const IID& iid, IComponent* component) = 0; virtual ComPtr Get(const IID& iid) noexcept = 0; virtual void Remove(const IID& iid) noexcept = 0; virtual void ReleaseAll() = 0; template ComPtr Get() { return TypedGet::Get(); } }; struct DECLSPEC_UUID("{C942AA9B-C576-4D3F-A54F-B135B500E611}") IComponentContainer;