]> git.tdb.fi Git - libs/game.git/blobdiff - source/game/component.h
Decorate things which constitute the public API of the library
[libs/game.git] / source / game / component.h
index 6b49dd19e8c6e3f64da05ceb550616d1e2c31624..e97b511a6ed658edbc9c221b2ca14a7ffa2927f7 100644 (file)
@@ -2,13 +2,15 @@
 #define MSP_GAME_COMPONENT_H_
 
 #include <msp/time/timedelta.h>
+#include "accessguard.h"
 #include "handle.h"
+#include "mspgame_api.h"
 
 namespace Msp::Game {
 
 class Entity;
 
-class Component
+class MSPGAME_API Component
 {
 protected:
        Handle<Entity> entity;
@@ -20,6 +22,51 @@ public:
        Handle<Entity> get_entity() const { return entity; }
 };
 
+template<typename T>
+class BufferedComponent: public Component
+{
+public:
+       using Data = T;
+       
+protected:
+       T data[2];
+       uint8_t read_index = 0;
+       uint8_t write_index = 0;
+       bool written = false;
+
+       BufferedComponent(Handle<Entity> e): Component(e) { }
+
+       const T &read() const;
+       T &write();
+
+public:
+       virtual void prepare_tick() { write_index = 1-read_index; written = false; }
+       virtual void commit_tick() { if(written) read_index = write_index; }
+};
+
+template<typename T>
+const T &BufferedComponent<T>::read() const
+{
+#ifdef DEBUG
+       AccessGuard::get_instance().check<AccessGuard::Read<T>>();
+#endif
+       return data[read_index];
+}
+
+template<typename T>
+T &BufferedComponent<T>::write()
+{
+#ifdef DEBUG
+       AccessGuard::get_instance().check<AccessGuard::Write<T>>();
+#endif
+       if(!written && write_index!=read_index)
+       {
+               data[write_index] = data[read_index];
+               written = true;
+       }
+       return data[write_index];
+}
+
 } // namespace Msp::Game
 
 #endif