#include "BufferLayer.h" #include "Main.h" #include "resource.h" #define killEvent events[0] #define startEvent events[1] enum { KILL_EVENT = 0, START_EVENT = 1, }; DWORD WINAPI BufferLayer::BufThread_stub(void *ptr) { ((BufferLayer *)ptr)->BufThread(); return 0; } BufferLayer::BufferLayer(IWMReader *reader) : reader2(0), buffering(false) { if (FAILED(reader->QueryInterface(&reader2))) reader2 = 0; startEvent = CreateEvent(NULL, TRUE, FALSE, NULL); killEvent = CreateEvent(NULL, FALSE, FALSE, NULL); DWORD id; thread = CreateThread(NULL, 128*1024, BufThread_stub, (void *)this, NULL, &id); } BufferLayer::~BufferLayer() { SetEvent(killEvent); ResetEvent(startEvent); WaitForSingleObject(thread, INFINITE); if (reader2) reader2->Release(); reader2 = 0; } void BufferLayer::BufferingStarted() { winamp.SetStatus(WASABI_API_LNGSTRINGW(IDS_BUFFERING)); buffering=true; SetEvent(startEvent); WMHandler::BufferingStarted(); } void BufferLayer::BufferingStopped() { winamp.SetStatus(L""); buffering=false; ResetEvent(startEvent); WMHandler::BufferingStopped(); } int BufferLayer::Wait() { if (WaitForSingleObject(killEvent, 0) == WAIT_OBJECT_0) return KILL_EVENT; return WaitForMultipleObjects(2, events, FALSE, INFINITE) - WAIT_OBJECT_0; } void BufferLayer::BufThread() { do { switch (Wait()) { case KILL_EVENT: return ; case START_EVENT: { if (reader2) { DWORD percent; QWORD throwAway; if (SUCCEEDED(reader2->GetBufferProgress(&percent, &throwAway))) winamp.Buffering(percent, WASABI_API_LNGSTRINGW(IDS_BUFFERING)); } Sleep(10); } continue; } } while (true); } void BufferLayer::OpenFailed() { ResetEvent(startEvent); WMHandler::OpenFailed(); }