Mercurial > vba-clojure
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_H20 #define RINGBUFFER_H22 #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