Double Buffering for Game objects, what's a nice clean generic C++ way?
c++, class, oop, operator-overloading, operators
Solution
I recently dealt with a similar desire in a generalized way by "snapshotting" a data structure that used Copy-On-Write under the hood. An aspect I like of this strategy is that you can make many snapshots if you need them, or just have one at a time to get your "double buffer".
Without sweating too many implementation details, here's some pseudocode:
snapshottable<Vector3> data;
data.writable().x = 5; // write to the member x
// take read-only snapshot
const snapshottable<Vector3>::snapshot snap (data.createSnapshot());
// since no writes have happened yet, snap and data point to the same object
int a = snap.x; //would read from the old buffer's x member, e.g. 5
data.writable().x += 1; //this non-const access triggers a copy
// data & snap are now pointing to different objects in memory
// data.readable().x == 6, while snap.x == 5
In your case, you'd snapshot your state and pass it to render. Then you'd allow your update to operate on the original object. Reading it with const access through `readable()` would not trigger a copy... while accessing with `writable()` would trigger a copy.
I used some tricks on top of Qt's QSharedDataPointer to do this. They differentiate const and non-const access via (->), such that reads from a const object won't trigger the copy on write mechanics.
Problem
This is in C++. So, I'm starting from scratch writing a game engine for fun and learning from the ground up. One of the ideas I want to implement is to have game object state (a struct) be double-buffered. For instance, I can have subsystems updating the new game object data while a render thread is rendering from the old data by guaranteeing there is a consistent state stored within the game object (the data from last time). After rendering of old and updating of new is finished, I can swap buffers and do it again. Question is, what's a good forward-looking and generic OOP way to expose this to my classes while trying to hide implementation details as much as possible? Would like to know your thoughts and considerations. I was thinking operator overloading could be used, but how do I overload assign for a templated class's member within my buffer class? for instance, I think this is an example of what I want: ``` doublebuffer<Vector3> data; data.x=5; //would write to the member x within the new buffer int a=data.x; //would read from the old buffer's x member data.x+=1; //I guess this shouldn't be allowed ``` If this is possible, I could choose to enable or disable double-buffering structs without changing much code. This is what I was considering: ``` template <class T> class doublebuffer{ T T1; T T2; T * current=T1; T * old=T2; public: doublebuffer(); ~doublebuffer(); void swap(); operator=()?... }; ``` and a game object would be like this: ``` struct MyObjectData{ int x; float afloat; } class MyObject: public Node { doublebuffer<MyObjectData> data; functions... } ``` What I have right now is functions that return pointers to the old and new buffer, and I guess any classes that use them have to be aware of this. Is there a better way?