view src/sdl/RingBuffer.h @ 336:25b7bb7da3b1

Fixed two major bugs related to restart events which were causing desync. The entire video now syncs properly.
author Robert McIntyre <rlm@mit.edu>
date Sat, 07 Apr 2012 07:31:59 -0500
parents f9f4f1b99eed
children
line wrap: on
line source
1 /***************************************************************************
2 * Copyright (C) 2008 by Sindre AamÄs *
3 * aamas@stud.ntnu.no *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License version 2 as *
7 * published by the Free Software Foundation. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License version 2 for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * version 2 along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19 #ifndef RINGBUFFER_H
20 #define RINGBUFFER_H
22 #include "Array.h"
23 #include <cstddef>
24 #include <algorithm>
25 #include <cstring>
27 template<typename T>
28 class RingBuffer {
29 Array<T> buf;
30 std::size_t sz;
31 std::size_t rpos;
32 std::size_t wpos;
34 public:
35 RingBuffer(const std::size_t sz_in = 0) : sz(0), rpos(0), wpos(0) { reset(sz_in); }
37 std::size_t avail() const {
38 return (wpos < rpos ? 0 : sz) + rpos - wpos - 1;
39 }
41 void clear() {
42 wpos = rpos = 0;
43 }
45 void fill(T value);
47 void read(T *out, std::size_t num);
49 void reset(std::size_t sz_in);
51 std::size_t size() const {
52 return sz - 1;
53 }
55 std::size_t used() const {
56 return (wpos < rpos ? sz : 0) + wpos - rpos;
57 }
59 void write(const T *in, std::size_t num);
60 };
62 template<typename T>
63 void RingBuffer<T>::fill(const T value) {
64 std::fill(buf + 0, buf + sz, value);
65 rpos = 0;
66 wpos = sz - 1;
67 }
69 template<typename T>
70 void RingBuffer<T>::read(T *out, std::size_t num) {
71 if (rpos + num > sz) {
72 const std::size_t n = sz - rpos;
74 std::memcpy(out, buf + rpos, n * sizeof(T));
76 rpos = 0;
77 num -= n;
78 out += n;
79 }
81 std::memcpy(out, buf + rpos, num * sizeof(T));
83 if ((rpos += num) == sz)
84 rpos = 0;
85 }
87 template<typename T>
88 void RingBuffer<T>::reset(const std::size_t sz_in) {
89 sz = sz_in + 1;
90 rpos = wpos = 0;
91 buf.reset(sz_in ? sz : 0);
92 }
94 template<typename T>
95 void RingBuffer<T>::write(const T *in, std::size_t num) {
96 if (wpos + num > sz) {
97 const std::size_t n = sz - wpos;
99 std::memcpy(buf + wpos, in, n * sizeof(T));
101 wpos = 0;
102 num -= n;
103 in += n;
104 }
106 std::memcpy(buf + wpos, in, num * sizeof(T));
108 if ((wpos += num) == sz)
109 wpos = 0;
110 }
112 #endif