2 [momiji music component library]
3 ---------------------------------------------------------------------
6 ---------------------------------------------------------------------
7 Copyright (C) 2011 tyiki badwell {miria@users.sourceforge.jp}.
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/gpl-3.0.html>.
21 ---------------------------------------------------------------------
25 #include "Momiji.Core.Buffer.h"
31 generic<typename DATA_TYPE>
32 BufferPool<DATA_TYPE>::Buffer::Buffer(Allocator^ allocator)
33 :_allocator(allocator)
36 System::Console::WriteLine("[{0}]",__FUNCTION__);
42 generic<typename DATA_TYPE>
43 BufferPool<DATA_TYPE>::Buffer::~Buffer()
46 System::Console::WriteLine("[{0}]",__FUNCTION__);
51 generic<typename DATA_TYPE>
52 BufferPool<DATA_TYPE>::Buffer::!Buffer()
55 System::Console::WriteLine("[{0}]",__FUNCTION__);
60 generic<typename DATA_TYPE>
61 void BufferPool<DATA_TYPE>::Buffer::Alloc()
64 System::Console::WriteLine("[{0}]",__FUNCTION__);
67 this->_buffer = this->_allocator();
68 this->_bufferHandle = InteropServices::GCHandle::Alloc(this->_buffer, InteropServices::GCHandleType::Pinned);
71 generic<typename DATA_TYPE>
72 void BufferPool<DATA_TYPE>::Buffer::Free()
75 System::Console::WriteLine("[{0}]",__FUNCTION__);
77 if (this->_bufferHandle.IsAllocated)
79 this->_bufferHandle.Free();
84 generic<typename DATA_TYPE>
85 System::IntPtr BufferPool<DATA_TYPE>::Buffer::GetBufferIntPtr()
87 return this->_bufferHandle.AddrOfPinnedObject();
90 generic<typename DATA_TYPE>
91 DATA_TYPE% BufferPool<DATA_TYPE>::Buffer::GetBuffer()
94 System::Console::WriteLine("[{0}]",__FUNCTION__);
105 generic<typename DATA_TYPE>
106 BufferPool<DATA_TYPE>::BufferPool(
107 System::UInt32 defaultPoolSize,
109 ): _allocator(allocator),
110 _buffers(gcnew System::Collections::Generic::List<Buffer^>()),
111 _idleBuffers(gcnew System::Collections::Generic::Dictionary<System::IntPtr, Buffer^>()),
112 _busyBuffers(gcnew System::Collections::Generic::Dictionary<System::IntPtr, Buffer^>()),
113 _defaultPoolSize(defaultPoolSize)
116 System::Console::WriteLine("[{0}]",__FUNCTION__);
119 for (System::UInt32 i = 0; i < this->_defaultPoolSize; i++)
125 generic<typename DATA_TYPE>
126 BufferPool<DATA_TYPE>::~BufferPool()
129 System::Console::WriteLine("[{0}]",__FUNCTION__);
134 generic<typename DATA_TYPE>
135 BufferPool<DATA_TYPE>::!BufferPool()
138 System::Console::WriteLine("[{0}]",__FUNCTION__);
141 for each (Buffer^ buffer in this->_buffers)
145 this->_buffers->Clear();
146 this->_idleBuffers->Clear();
147 this->_busyBuffers->Clear();
150 generic<typename DATA_TYPE>
151 BufferPool<DATA_TYPE>::Buffer^ BufferPool<DATA_TYPE>::Get()
154 System::Console::WriteLine("[{0}]",__FUNCTION__);
157 System::Threading::Monitor::Enter(this);
160 if (this->_idleBuffers->Count == 0)
162 //暇なバッファが無ければ、1回分のバッファを新規作成
166 System::Collections::Generic::KeyValuePair<System::IntPtr, Buffer^> pair =
167 System::Linq::Enumerable::First(this->_idleBuffers);
169 System::Console::WriteLine("[{0}] buffer ptr[{1}]", __FUNCTION__, pair.Key);
172 Buffer^ buffer = pair.Value;
173 auto intPtr = buffer->GetBufferIntPtr();
174 if (!this->_idleBuffers->Remove(intPtr))
176 throw gcnew System::Exception("バッファの確保に失敗しました。");
178 this->_busyBuffers->Add(intPtr, buffer);
181 System::Console::WriteLine("[{0}] alloc[{1}] idle[{2}] busy[{3}]", __FUNCTION__, this->_buffers->Count, this->_idleBuffers->Count, this->_busyBuffers->Count);
188 System::Threading::Monitor::Exit(this);
192 generic<typename DATA_TYPE>
193 BufferPool<DATA_TYPE>::Buffer^ BufferPool<DATA_TYPE>::GetBusy(System::IntPtr bufferPtr)
196 System::Console::WriteLine("[{0}][{1}]",__FUNCTION__, bufferPtr);
199 BufferPool<DATA_TYPE>::Buffer^ buffer = nullptr;
200 if (!this->_busyBuffers->TryGetValue(bufferPtr, buffer))
202 throw gcnew System::Exception("使用済みバッファの取得に失敗しました。");
208 generic<typename DATA_TYPE>
209 void BufferPool<DATA_TYPE>::Release(Buffer^ buffer)
212 System::Console::WriteLine("[{0}]",__FUNCTION__);
215 System::Threading::Monitor::Enter(this);
218 auto intPtr = buffer->GetBufferIntPtr();
219 if (!this->_busyBuffers->Remove(intPtr))
221 throw gcnew System::Exception("使用済みバッファの開放に失敗しました。");
224 System::Console::WriteLine("[{0}] buffer ptr[{1}]", __FUNCTION__, intPtr);
226 this->_idleBuffers->Add(intPtr, buffer);
229 System::Console::WriteLine("[{0}] alloc[{1}] idle[{2}] busy[{3}]", __FUNCTION__, this->_buffers->Count, this->_idleBuffers->Count, this->_busyBuffers->Count);
234 System::Threading::Monitor::Exit(this);
238 generic<typename DATA_TYPE>
239 BufferPool<DATA_TYPE>::Buffer^ BufferPool<DATA_TYPE>::MakeBuffer()
242 System::Console::WriteLine("[{0}]",__FUNCTION__);
245 BufferPool<DATA_TYPE>::Buffer^ buffer = gcnew BufferPool<DATA_TYPE>::Buffer(this->_allocator);
246 this->_buffers->Add(buffer);
247 this->_idleBuffers->Add(buffer->GetBufferIntPtr(), buffer);
250 System::Console::WriteLine("[{0}] alloc[{1}] idle[{2}] busy[{3}]", __FUNCTION__, this->_buffers->Count, this->_idleBuffers->Count, this->_busyBuffers->Count);
256 generic<typename DATA_TYPE>
257 System::Boolean BufferPool<DATA_TYPE>::IsBusy()
259 return (this->_busyBuffers->Count > 0);