#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2013 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_GRAPHICS_RASTERIZATION_DIRECT3D11OBSERVERMANAGER_H #define NUCLEX_GRAPHICS_RASTERIZATION_DIRECT3D11OBSERVERMANAGER_H #include "Nuclex/Graphics/Config.h" #include "Direct3D11Api.h" #include #include namespace Nuclex { namespace Graphics { namespace Rasterization { // ------------------------------------------------------------------------------------------- // class Direct3D11RasterizerResources; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Graphics::Rasterization namespace Nuclex { namespace Graphics { namespace Rasterization { // ------------------------------------------------------------------------------------------- // /// Manages resources of the holder's specialized type /// Agnostic resource observers are attached to /// Observer that maintains the Direct3D 11 resource template class Direct3D11ObserverManager { /// Initializes a new resource holder /// Resource manager the observers will belong to protected: Direct3D11ObserverManager(Direct3D11RasterizerResources *resources) : resources(resources) {} /// Frees all resources owned by the instance public: ~Direct3D11ObserverManager() {} /// Kills all observers of the resource holder protected: void EvictAll() { while(!this->observers.empty()) { ObserverSet::iterator iterator = this->observers.begin(); TObserver *observer = *iterator; Evict(observer->GetResource(), observer); } } /// Retrieves the resource's attached observer /// /// Resource whose currently attached observer will be returned /// /// The observer currently attached to the specified resource protected: TObserver *Get(TAgnostic *resource) { auto observer = resource->GetObserver(this); return static_cast(observer); // downcast } /// Attaches an observer to the resource or returns its current one /// /// Resource an observer will be attached to or whose current observer will be returned /// /// The observer for the specified resource protected: TObserver *Prepare(TAgnostic *resource) { auto observer = resource->GetObserver(this); if(observer == nullptr) { TObserver *d3dObserver = new TObserver(*this->resources, resource); this->observers.insert(d3dObserver); resource->AttachObserver(this, d3dObserver); return d3dObserver; } else { return static_cast(observer); // downcast } } /// Kills the observer for the specified resource /// Resource whose observer will be killed /// Observer that will be killed, if known protected: void Evict(TAgnostic *resource, TObserver *observer = nullptr) { // If the caller didn't know the observer, look it up. We may find that there // is no observer attached in that case, meaning the resource is already evicted. if(observer == nullptr) { observer = static_cast(resource->GetObserver(this)); if(observer == nullptr) { return; // Has already been evicted } } // Remove the observer from our tracking set and kill it. ObserverSet::iterator iterator = this->observers.find(observer); if(iterator == this->observers.end()) { throw std::logic_error("Internal observer management error"); } else { this->observers.erase(iterator); resource->DetachObserver(this); delete observer; } } /// A set of observers for the resource private: typedef std::set ObserverSet; /// Observers for vertex buffers the user has created private: ObserverSet observers; /// Resource manager for which this holder is managing a resource private: Direct3D11RasterizerResources *resources; }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Graphics::Rasterization #endif // NUCLEX_GRAPHICS_RASTERIZATION_DIRECT3D11OBSERVERMANAGER_H