Add <functional> to files that use std::function
[lsnes.git] / include / library / triplebuffer.hpp
blob09861aa60a7944ba1be9ce788a2f4deddeeabaed
1 #ifndef _library_triplebuffer__hpp__included__
2 #define _library_triplebuffer__hpp__included__
4 #include <functional>
5 #include <stdexcept>
6 #include "threads.hpp"
8 namespace triplebuffer
10 /**
11 * Triple-buffering logic.
13 class logic
15 public:
16 /**
17 * Create a new triple buffer.
19 logic() throw();
20 /**
21 * Get read pointer and increment read count by 1.
23 * Return value: Read pointer (0-2).
25 * Note: If read count is zero, last complete buffer is returned. Otherwise the same buffer as last call is returned.
27 unsigned get_read() throw();
28 /**
29 * Put read pointer and decrement read count by 1.
31 * Throws std::logic_error: If read count is 0.
33 void put_read() throw(std::logic_error);
34 /**
35 * Get write pointer and increment write count by 1.
37 * Return value: Write pointer (0-2).
39 * Note: If write count is nonzero before call, the returned buffer is the same as last time.
41 unsigned get_write() throw();
42 /**
43 * Put write pointer and decrement write count by 1. If write count hits 0, the buffer is marked as last complete
44 * buffer.
46 * Throws std::logic_error: If write count is 0.
48 void put_write() throw(std::logic_error);
49 /**
50 * Call specified function synchronously for last written buffer.
52 * The buffer number is passed to specified function.
54 void read_last_write_synchronous(std::function<void(unsigned)> fn) throw();
55 private:
56 threads::lock lock;
57 unsigned last_complete; //Number of last completed buffer
58 unsigned current_read; //Number of current read buffer (only valid if count_read > 0).
59 unsigned current_write; //Number of current write buffer (only valid if count_write > 0).
60 unsigned count_read; //Number of readers.
61 unsigned count_write; //Number of writers.
64 /**
65 * Triple buffer with objects.
67 template<typename T>
68 class triplebuffer
70 public:
71 /**
72 * Create a new triple buffer.
74 * Parameter A: Object #1.
75 * Parameter B: Object #2.
76 * Parameter C: Object #3.
78 triplebuffer(T& A, T& B, T& C) throw()
80 objs[0] = &A;
81 objs[1] = &B;
82 objs[2] = &C;
84 /**
85 * Get read pointer and increment read count by 1.
87 * Return value: Read pointer.
89 * Note: If read count is zero, last complete buffer is returned. Otherwise the same buffer as last call is returned.
91 T& get_read() throw() { return *objs[l.get_read()]; }
92 /**
93 * Put read pointer and decrement read count by 1.
95 * Throws std::logic_error: If read count is 0.
97 void put_read() throw(std::logic_error) { l.put_read(); }
98 /**
99 * Get write pointer and increment write count by 1.
101 * Return value: Write pointer.
103 * Note: If write count is nonzero before call, the returned buffer is the same as last time.
105 T& get_write() throw() { return *objs[l.get_write()]; }
107 * Put write pointer and decrement write count by 1. If write count hits 0, the buffer is marked as last complete
108 * buffer.
110 * Throws std::logic_error: If write count is 0.
112 void put_write() throw(std::logic_error) { l.put_write(); }
114 * Call specified function synchronously for last written buffer.
116 * The buffer itself is passed to the function.
118 void read_last_write_synchronous(std::function<void(T&)> fn) throw()
120 l.read_last_write_synchronous([this,fn](unsigned x){ fn(*objs[x]); });
122 private:
123 T* objs[3];
124 logic l;
128 #endif