]> git.tdb.fi Git - libs/game.git/blob - source/game/component.h
Decorate things which constitute the public API of the library
[libs/game.git] / source / game / component.h
1 #ifndef MSP_GAME_COMPONENT_H_
2 #define MSP_GAME_COMPONENT_H_
3
4 #include <msp/time/timedelta.h>
5 #include "accessguard.h"
6 #include "handle.h"
7 #include "mspgame_api.h"
8
9 namespace Msp::Game {
10
11 class Entity;
12
13 class MSPGAME_API Component
14 {
15 protected:
16         Handle<Entity> entity;
17
18         Component(Handle<Entity>);
19 public:
20         virtual ~Component() = default;
21
22         Handle<Entity> get_entity() const { return entity; }
23 };
24
25 template<typename T>
26 class BufferedComponent: public Component
27 {
28 public:
29         using Data = T;
30         
31 protected:
32         T data[2];
33         uint8_t read_index = 0;
34         uint8_t write_index = 0;
35         bool written = false;
36
37         BufferedComponent(Handle<Entity> e): Component(e) { }
38
39         const T &read() const;
40         T &write();
41
42 public:
43         virtual void prepare_tick() { write_index = 1-read_index; written = false; }
44         virtual void commit_tick() { if(written) read_index = write_index; }
45 };
46
47 template<typename T>
48 const T &BufferedComponent<T>::read() const
49 {
50 #ifdef DEBUG
51         AccessGuard::get_instance().check<AccessGuard::Read<T>>();
52 #endif
53         return data[read_index];
54 }
55
56 template<typename T>
57 T &BufferedComponent<T>::write()
58 {
59 #ifdef DEBUG
60         AccessGuard::get_instance().check<AccessGuard::Write<T>>();
61 #endif
62         if(!written && write_index!=read_index)
63         {
64                 data[write_index] = data[read_index];
65                 written = true;
66         }
67         return data[write_index];
68 }
69
70 } // namespace Msp::Game
71
72 #endif