OIS  1.5
Object-oriented Input System
OISLIRCRingBuffer.h
Go to the documentation of this file.
1 #include "OISConfig.h"
2 #ifdef OIS_LIRC_SUPPORT
3 /*
4 The zlib/libpng License
5 
6 Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
7 
8 This software is provided 'as-is', without any express or implied warranty. In no event will
9 the authors be held liable for any damages arising from the use of this software.
10 
11 Permission is granted to anyone to use this software for any purpose, including commercial
12 applications, and to alter it and redistribute it freely, subject to the following
13 restrictions:
14 
15  1. The origin of this software must not be misrepresented; you must not claim that
16  you wrote the original software. If you use this software in a product,
17  an acknowledgment in the product documentation would be appreciated but is
18  not required.
19 
20  2. Altered source versions must be plainly marked as such, and must not be
21  misrepresented as being the original software.
22 
23  3. This notice may not be removed or altered from any source distribution.
24 
25  # ------------------------#
26  # Original License follows:
27  # ------------------------#
28 
29  * PortAudio Portable Real-Time Audio Library
30  * Latest version at: http://www.audiomulch.com/portaudio/
31  * <platform> Implementation
32  * Copyright (c) 1999-2000 <author(s)>
33  *
34  * Permission is hereby granted, free of charge, to any person obtaining
35  * a copy of this software and associated documentation files
36  * (the "Software"), to deal in the Software without restriction,
37  * including without limitation the rights to use, copy, modify, merge,
38  * publish, distribute, sublicense, and/or sell copies of the Software,
39  * and to permit persons to whom the Software is furnished to do so,
40  * subject to the following conditions:
41  *
42  * The above copyright notice and this permission notice shall be
43  * included in all copies or substantial portions of the Software.
44  *
45  * Any person wishing to distribute modifications to the Software is
46  * requested to send the modifications to the original developer so that
47  * they can be incorporated into the canonical version.
48  *
49  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
50  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
52  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
53  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
54  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
55  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
56  */
57 #ifndef OIS_LIRCRingBuffer_H
58 #define OIS_LIRCRingBuffer_H
59 
60 #include "OISPrereqs.h"
61 
62 namespace OIS
63 {
64  struct LIRCEvent
65  {
67  unsigned int button;
68  };
69 
73  class LIRCRingBuffer
74  {
75  private:
77  int bufferSize;
79  int bigMask;
80  // Used for fitting indices to buffer.
81  int smallMask;
82 
83  // Buffer holding the actual event buffers
84  LIRCEvent* buffer;
85 
87  volatile int writeIndex;
88 
90  volatile int readIndex;
91 
92  public:
93  LIRCRingBuffer(unsigned int numEntries)
94  {
95  numEntries = RoundUpToNextPowerOf2(numEntries);
96 
97  //2 bytes per short
98  bufferSize = (int)numEntries;
99  buffer = new LIRCEvent[numEntries];
100 
101  Flush();
102 
103  bigMask = (int)(numEntries * 2) - 1;
104  smallMask = (int)(numEntries)-1;
105  }
106 
107  ~LIRCRingBuffer()
108  {
109  delete buffer;
110  }
111 
112  unsigned int RoundUpToNextPowerOf2(unsigned int n)
113  {
114  int numBits = 0;
115  if(((n - 1) & n) == 0)
116  return n; //Already Power of two.
117 
118  while(n > 0)
119  {
120  n = n >> 1;
121  numBits++;
122  }
123  return (unsigned int)(1 << numBits);
124  }
125 
126  int GetReadAvailable()
127  {
128  return ((writeIndex - readIndex) & bigMask);
129  }
130 
131  int GetWriteAvailable()
132  {
133  return (bufferSize - GetReadAvailable());
134  }
135 
136  int Write(LIRCEvent* data, int numEntries)
137  {
138  int size1 = 0, size2 = 0, numWritten;
139  int data1Ptr = 0, data2Ptr = 0;
140 
141  numWritten = GetWriteRegions(numEntries, data1Ptr, size1, data2Ptr, size2);
142 
143  if(size2 > 0)
144  {
145  //copy to two parts
146  memcpy(&buffer[data1Ptr], data, sizeof(LIRCEvent) * size1);
147  //Array.Copy( data, offsetPtr, buffer, data1Ptr, size1 );
148  memcpy(&buffer[data2Ptr], &data[size1], sizeof(LIRCEvent) * size2);
149  //Array.Copy( data, offsetPtr + size1, buffer, data2Ptr, size2 );
150  }
151  else
152  { //Copy all continous
153  memcpy(&buffer[data1Ptr], data, sizeof(LIRCEvent) * size1);
154  //Array.Copy( data, offsetPtr, buffer, data1Ptr, size1 );
155  }
156  AdvanceWriteIndex(numWritten);
157  return numWritten;
158  }
159 
164  int Read(LIRCEvent* data, int numEntries)
165  {
166  int size1 = 0, size2 = 0, numRead, data1Ptr = 0, data2Ptr = 0;
167 
168  numRead = GetReadRegions(numEntries, data1Ptr, size1, data2Ptr, size2);
169 
170  if(size2 > 0)
171  {
172  memcpy(data, &buffer[data1Ptr], sizeof(LIRCEvent) * size1);
173  //Array.Copy( buffer, data1Ptr, data, 0, size1 );
174  memcpy(&data[size1], &buffer[data2Ptr], sizeof(LIRCEvent) * size2);
175  //Array.Copy( buffer, data2Ptr, data, size1, size2 );
176  }
177  else
178  memcpy(data, &buffer[data1Ptr], sizeof(LIRCEvent) * size1);
179  //Array.Copy( buffer, data1Ptr, data, 0, size1 );
180 
181  AdvanceReadIndex(numRead);
182  return numRead;
183  }
184 
185  private:
186  int GetWriteRegions(int numEntries, int& dataPtr1, int& sizePtr1, int& dataPtr2, int& sizePtr2)
187  {
188  int index;
189  int available = GetWriteAvailable();
190  if(numEntries > available)
191  numEntries = available;
192 
193  //Check to see if write is not contiguous.
194  index = writeIndex & smallMask;
195  if((index + numEntries) > bufferSize)
196  {
197  //Write data in two blocks that wrap the buffer.
198  int firstHalf = bufferSize - index;
199  dataPtr1 = index; //&buffer[index];
200  sizePtr1 = firstHalf;
201  dataPtr2 = 0; //&buffer[0];
202  sizePtr2 = numEntries - firstHalf;
203  }
204  else
205  {
206  dataPtr1 = index; //&buffer[index];
207  sizePtr1 = numEntries;
208  dataPtr2 = 0;
209  sizePtr2 = 0;
210  }
211  return numEntries;
212  }
213 
214  int GetReadRegions(int numEntries, int& dataPtr1, int& sizePtr1, int& dataPtr2, int& sizePtr2)
215  {
216  int index;
217  int available = GetReadAvailable();
218  if(numEntries > available)
219  numEntries = available;
220 
221  // Check to see if read is not contiguous
222  index = readIndex & smallMask;
223  if((index + numEntries) > bufferSize)
224  {
225  // Write data in two blocks that wrap the buffer
226  int firstHalf = bufferSize - index;
227  dataPtr1 = index; //&buffer[index];
228  sizePtr1 = firstHalf;
229  dataPtr2 = 0; //&buffer[0];
230  sizePtr2 = numEntries - firstHalf;
231  }
232  else
233  {
234  dataPtr1 = index; //&buffer[index];
235  sizePtr1 = numEntries;
236  dataPtr2 = 0;
237  sizePtr2 = 0;
238  }
239  return numEntries;
240  }
241 
242  int AdvanceWriteIndex(int numEntries)
243  {
244  return writeIndex = (writeIndex + numEntries) & bigMask;
245  }
246 
247  int AdvanceReadIndex(int numEntries)
248  {
249  return readIndex = (readIndex + numEntries) & bigMask;
250  }
251 
252  void Flush()
253  {
254  writeIndex = readIndex = 0;
255  }
256  };
257 }
258 #endif //#define OIS_LIRCRingBuffer_H
259 #endif
Definition: OISEffect.h:28