class Buffer;
+/**
+Base class for things that can store data in buffers. Supports buffer sharing.
+A dirty flag is provided for derived classes. It should be set when the data
+in the buffer is considered out of date, and is cleared by Bufferable after
+uploading fresh data to the buffer.
+*/
class Bufferable
{
-protected:
+private:
Buffer *buffer;
- unsigned buffer_offset;
+ unsigned offset;
Bufferable *next_in_buffer;
Bufferable *prev_in_buffer;
+protected:
mutable bool dirty;
+protected:
Bufferable();
public:
virtual ~Bufferable();
- void use_buffer(Buffer *, Bufferable * = 0);
+ /** Sets the buffer to use. If prev is not null, it must use the same
+ buffer, and this object is inserted after it. */
+ void use_buffer(Buffer *buf, Bufferable *prev = 0);
+
private:
void unlink_from_buffer();
protected:
+ /** Returns the buffer in which the data is stored. */
+ Buffer *get_buffer() const { return buffer; }
+
+ /** Returns the amount of data to be stored in the buffer, in bytes. */
virtual unsigned get_data_size() const = 0;
- void update_buffer_offset();
+ /** Returns the alignment required for the data, in bytes. The offset is
+ guaranteed to be a multiple of this. */
+ virtual unsigned get_alignment() const { return 1; }
+
+ /** Updates the offsets for the chain so that data from different objects
+ does not overlap. Should be called if either data size or alignment
+ changes. */
+ void update_offset();
+
+ /** Returns the offset where the data should be uploaded. */
+ unsigned get_offset() const { return offset; }
+
+ /** Called when the offset for the data has changed. */
virtual void offset_changed() { }
- void update_buffer_data() const;
+ /** Resizes the buffer if necessary and calls upload_data(). */
+ void update_buffer() const;
+
+ /** Uploads data to the buffer. */
virtual void upload_data() const = 0;
};