annotate src/sdl/RingBuffer.h @ 316:d263df762c59

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