#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_BUFFER_H #define NUCLEX_GRAPHICS_RASTERIZATION_BUFFER_H #include "Resource.h" #include "Usage.h" #include "../Helpers/ConcurrentObserverSet.h" #include namespace Nuclex { namespace Graphics { namespace Rasterization { // ------------------------------------------------------------------------------------------- // ///Stores sequential data for the vertex shader class Buffer : public Resource { #pragma region class Observer /// Receives notifications from the buffer when it changes public: class Observer : public Resource::Observer { /// Frees the resources used by the observer public: virtual ~Observer() {} /// Called right before the buffer is destroyed public: virtual void Destroying() = 0; /// Called when the buffer has been cleared public: virtual void Cleared() = 0; /// Called when the contents of the buffer have changed /// /// Offset in the buffer from which on its contents have changed /// /// Number of bytes that have changed in the buffer /// /// Offset and count are always specified in bytes. /// public: virtual void Changed(std::size_t offset, std::size_t count) = 0; }; #pragma endregion // class Observer /// Initializes a new buffer with the specified capacity /// Number of bytes to reserve for this buffer protected: NUCLEX_GRAPHICS_API Buffer(std::size_t capacityInBytes); /// Creates a copy of an existing buffer /// Existing buffer that will be copied /// /// The copy will not take over the existing buffer's attached observers. /// protected: NUCLEX_GRAPHICS_API Buffer(const Buffer &other); /// Destroys the buffer public: NUCLEX_GRAPHICS_API virtual ~Buffer(); /// Returns the capacity of the buffer in bytes /// The number of bytes that fit in the buffer public: NUCLEX_GRAPHICS_API std::size_t GetCapacityInBytes() const { return this->CapacityBytes; } /// Returns the number of bytes used in the buffer /// The number of bytes the buffer has been filled with public: NUCLEX_GRAPHICS_API std::size_t CountUsedBytes() const { return this->usedBytes; } /// Resets the buffer to empty public: NUCLEX_GRAPHICS_API void Clear() { this->usedBytes = 0; OnCleared(); } /// Accesses the memory used by the buffer /// The memory storing the buffer contents public: NUCLEX_GRAPHICS_API const std::uint8_t *AccessMemory() const { return this->Contents; } /// Accesses the memory used by the buffer /// The memory storing the buffer contents public: NUCLEX_GRAPHICS_API std::uint8_t *AccessMemory() { return this->Contents; } /* /// Marks the specified region of the buffer as dirty /// Start offset, in public: NUCLEX_GRAPHICS_API void MarkDirty( std::size_t start, std::size_t count, bool okayToDiscardOtherContent = false ); */ /// Suppresses the notifications and begins queueing them /// /// Use this method if you plan to apply many small changes to the buffer in /// order to avoid the overhead that would result in any observers having /// to process hundreds of micro-changes. The buffer will collect all changes /// and merge them. Once notifications are enabled again, a single notification /// even will be fired, containing the changed area. /// public: NUCLEX_GRAPHICS_API void SuppressChangeNotifications(); /// Enables change notifications again /// /// If any changes happened while notifications were suppressed, this will /// trigger a change notification. /// public: NUCLEX_GRAPHICS_API void PermitChangeNotifications(); /// Retrieves the observer attached by the specified owner /// Owner whose observer will be looked up /// The observer registered by the specified owner or a nullptr public: NUCLEX_GRAPHICS_API Observer *GetObserver(const void *owner) const; /// Attaches an observer to the buffer /// The observer's owner, used as a unique key /// Observer that will be attached to the buffer public: NUCLEX_GRAPHICS_API void AttachObserver(const void *owner, Observer *observer); /// Detaches the specified owner's observer from the buffer /// Owner whose observer will be detached public: NUCLEX_GRAPHICS_API void DetachObserver(const void *owner); /// Copies the contents of another buffer into this buffer /// Other buffer whose contents will be copied /// A reference to this buffer protected: NUCLEX_GRAPHICS_API Buffer &operator =(const Buffer &other); /// Notifies all observers that the buffer is about to be destroyed protected: NUCLEX_GRAPHICS_API void OnDestroying(); /// Notifies all observers that the buffer has been cleared protected: NUCLEX_GRAPHICS_API void OnCleared(); /// Notifies all observers that the buffer has been changed /// Offset from which on the buffer has been changed /// Number of bytes that have changed in the buffer protected: NUCLEX_GRAPHICS_API void OnChanged( std::size_t offset, std::size_t count ); /// The buffer's capacity in bytes protected: const std::size_t CapacityBytes; /// The contents of the buffer /// /// The buffer pointer is constant (since a buffer is allocated once and cannot be /// resized or replaced), but the data is not. /// protected: std::uint8_t *const Contents; /// Used buffer space in bytes private: std::size_t usedBytes; /// Index of the first change whilst notifications are suppressed private: std::size_t firstChangeOffset; /// Index one past the last change whilst notifications are suppressed private: std::size_t lastChangeOffset; /// Observers to changes happening to the buffer private: Helpers::ConcurrentObserverSet observers; }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Graphics::Rasterization #endif // NUCLEX_GRAPHICS_RASTERIZATION_BUFFER_H