diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/devices/deviceManager.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/devices/deviceManager.cpp')
-rw-r--r-- | Src/devices/deviceManager.cpp | 650 |
1 files changed, 650 insertions, 0 deletions
diff --git a/Src/devices/deviceManager.cpp b/Src/devices/deviceManager.cpp new file mode 100644 index 00000000..a68eec69 --- /dev/null +++ b/Src/devices/deviceManager.cpp @@ -0,0 +1,650 @@ +#include "main.h" +#include "./deviceManager.h" +#include "./deviceEventManager.h" + +static void +DeviceManager_ReleaseDispatchables(Dispatchable** buffer, size_t count) +{ + if(NULL == buffer) + return; + + while(count--) + { + Dispatchable *object = buffer[count]; + if (NULL != object) + object->Release(); + } +} + +DeviceManager::DeviceManager() + : ref(1), + #pragma warning(push) + #pragma warning(disable:4355) + typeStore(ObjectAddedCallback, ObjectRemovedCallback, this), + connectionStore(ObjectAddedCallback, ObjectRemovedCallback, this), + commandStore(ObjectAddedCallback, ObjectRemovedCallback, this), + deviceStore(ObjectAddedCallback, ObjectRemovedCallback, this) + #pragma warning(pop) +{ + InitializeCriticalSection(&eventLock); + InitializeCriticalSection(&providerLock); +} + + +DeviceManager::~DeviceManager() +{ + EnterCriticalSection(&providerLock); + DeviceManager_ReleaseDispatchables((Dispatchable**)(providerList.size() ? &providerList.at(0) : nullptr), providerList.size()); + providerList.clear(); + LeaveCriticalSection(&providerLock); + DeleteCriticalSection(&providerLock); + + EnterCriticalSection(&eventLock); + DeviceManager_ReleaseDispatchables((Dispatchable**)(eventList.size() ? &eventList.at(0) : nullptr), eventList.size()); + eventList.clear(); + LeaveCriticalSection(&eventLock); + DeleteCriticalSection(&eventLock); +} + +HRESULT DeviceManager::CreateInstance(DeviceManager **instance) +{ + if (NULL == instance) + return E_POINTER; + + *instance = new DeviceManager(); + + if (NULL == *instance) + return E_OUTOFMEMORY; + + return S_OK; +} + +size_t DeviceManager::AddRef() +{ + return InterlockedIncrement((LONG*)&ref); +} + +size_t DeviceManager::Release() +{ + if (0 == ref) + return ref; + + LONG r = InterlockedDecrement((LONG*)&ref); + if (0 == r) + delete(this); + + return r; +} + +int DeviceManager::QueryInterface(GUID interface_guid, void **object) +{ + if (NULL == object) return E_POINTER; + + if (IsEqualIID(interface_guid, DeviceManagerGUID)) + *object = static_cast<api_devicemanager*>(this); + else + { + *object = NULL; + return E_NOINTERFACE; + } + + if (NULL == *object) + return E_UNEXPECTED; + + AddRef(); + return S_OK; +} + +size_t DeviceManager::TypeRegister(ifc_devicetype **types, size_t count) +{ + return typeStore.AddRange((ifc_deviceobject**)types, count); +} + +size_t DeviceManager::TypeRegisterIndirect(const char **names, size_t count, DeviceTypeCreator callback, void *user) +{ + return typeStore.AddIndirect(names, count, (DeviceObjectCreator)callback, user); +} + +HRESULT DeviceManager::TypeUnregister(const char *name) +{ + return typeStore.Remove(name); +} + +HRESULT DeviceManager::TypeFind(const char *name, ifc_devicetype **type) +{ + return typeStore.Find(name, (ifc_deviceobject**)type); +} + +HRESULT DeviceManager::TypeEnumerate(ifc_deviceobjectenum **enumerator) +{ + return typeStore.Enumerate((DeviceObjectEnum**)enumerator); +} + +size_t DeviceManager::ConnectionRegister(ifc_deviceconnection **connections, size_t count) +{ + + return connectionStore.AddRange((ifc_deviceobject**)connections, count); +} + +size_t DeviceManager::ConnectionRegisterIndirect(const char **names, size_t count, DeviceConnectionCreator callback, void *user) +{ + return connectionStore.AddIndirect(names, count, (DeviceObjectCreator)callback, user); +} + +HRESULT DeviceManager::ConnectionUnregister(const char *name) +{ + return connectionStore.Remove(name); +} + +HRESULT DeviceManager::ConnectionFind(const char *name, ifc_deviceconnection **connection) +{ + return connectionStore.Find(name, (ifc_deviceobject**)connection); +} + +HRESULT DeviceManager::ConnectionEnumerate(ifc_deviceobjectenum **enumerator) +{ + return connectionStore.Enumerate((DeviceObjectEnum**)enumerator); +} + +size_t DeviceManager::CommandRegister(ifc_devicecommand **commands, size_t count) +{ + return commandStore.AddRange((ifc_deviceobject**)commands, count); +} + +size_t DeviceManager::CommandRegisterIndirect(const char **names, size_t count, DeviceCommandCreator callback, void *user) +{ + return commandStore.AddIndirect(names, count, (DeviceObjectCreator)callback, user); +} + +HRESULT DeviceManager::CommandUnregister(const char *name) +{ + return commandStore.Remove(name); +} + +HRESULT DeviceManager::CommandFind(const char *name, ifc_devicecommand **command) +{ + return commandStore.Find(name, (ifc_deviceobject**)command); +} + +HRESULT DeviceManager::CommandEnumerate(ifc_deviceobjectenum **enumerator) +{ + return commandStore.Enumerate((DeviceObjectEnum**)enumerator); +} + +size_t DeviceManager::DeviceRegister(ifc_device **devices, size_t count) +{ + return deviceStore.AddRange((ifc_deviceobject**)devices, count); +} + +HRESULT DeviceManager::DeviceUnregister(const char *name) +{ + return deviceStore.Remove(name); +} + +HRESULT DeviceManager::DeviceFind(const char *name, ifc_device **device) +{ + return deviceStore.Find(name, (ifc_deviceobject**)device); +} + +HRESULT DeviceManager::DeviceEnumerate(ifc_deviceobjectenum **enumerator) +{ + return deviceStore.Enumerate((DeviceObjectEnum**)enumerator); +} + + +HRESULT DeviceManager::IsDiscoveryActive() +{ + return (FALSE != discoveryMonitor.IsActive()) ? S_OK : S_FALSE; +} + +HRESULT DeviceManager::BeginDiscovery() +{ + size_t index, started; + + EnterCriticalSection(&providerLock); + + started = 0; + index = providerList.size(); + + while(index--) + { + if (providerList[index] && SUCCEEDED(providerList[index]->BeginDiscovery((api_devicemanager*)this))) + started++; + } + + LeaveCriticalSection(&providerLock); + + return (0 != started) ? S_OK : E_FAIL; +} + +HRESULT DeviceManager::CancelDiscovery() +{ + size_t index; + + EnterCriticalSection(&providerLock); + + index = providerList.size(); + + while(index--) + { + providerList[index]->CancelDiscovery(); + } + + LeaveCriticalSection(&providerLock); + + return S_OK; +} + +HRESULT DeviceManager::SetProviderActive(ifc_deviceprovider *provider, BOOL activeState) +{ + + if (FALSE != activeState) + { + if (FALSE != discoveryMonitor.Register(provider)) + EventDiscoveryStarted(); + } + else + { + if (FALSE != discoveryMonitor.Unregister(provider)) + EventDiscoveryFinished(); + } + + return S_OK; +} + +HRESULT DeviceManager::RegisterProvider(ifc_deviceprovider *provider) +{ + HRESULT hr; + size_t index; + + if (NULL == provider) + return E_INVALIDARG; + + hr = S_OK; + + EnterCriticalSection(&providerLock); + + index = providerList.size(); + while(index--) + { + if (provider == providerList[index]) + { + hr = S_FALSE; + break; + } + } + + if(S_OK == hr) + { + providerList.push_back(provider); + provider->AddRef(); + + SetProviderActive(provider, (S_OK == provider->GetActive())); + } + + LeaveCriticalSection(&providerLock); + + return hr; +} + +HRESULT DeviceManager::UnregisterProvider(ifc_deviceprovider *provider) +{ + HRESULT hr; + size_t index; + + if (NULL == provider) + return E_INVALIDARG; + + hr = S_FALSE; + + EnterCriticalSection(&providerLock); + + index = providerList.size(); + while(index--) + { + if (provider == providerList[index]) + { + ifc_deviceprovider *object; + object = providerList[index]; + + SetProviderActive(object, (S_OK == object->GetActive())); + + providerList.erase(providerList.begin() + index); + object->Release(); + + hr = S_OK; + break; + } + } + + LeaveCriticalSection(&providerLock); + + return hr; +} + +HRESULT DeviceManager::Advise(ifc_devicemanagerevent *handler) +{ + HRESULT hr; + size_t index; + + if (NULL == handler) + return E_INVALIDARG; + + hr = S_OK; + + EnterCriticalSection(&eventLock); + + index = eventList.size(); + while(index--) + { + if (handler == eventList[index]) + { + hr = S_FALSE; + break; + } + } + + if(S_OK == hr) + { + eventList.push_back(handler); + handler->AddRef(); + } + + LeaveCriticalSection(&eventLock); + + return hr; +} + +HRESULT DeviceManager::Unadvise(ifc_devicemanagerevent *handler) +{ + HRESULT hr; + size_t index; + + if (NULL == handler) + return E_INVALIDARG; + + hr = S_FALSE; + + EnterCriticalSection(&eventLock); + + index = eventList.size(); + while(index--) + { + if (handler == eventList[index]) + { + ifc_devicemanagerevent *object; + object = eventList[index]; + + eventList.erase(eventList.begin() + index); + object->Release(); + + hr = S_OK; + break; + } + } + + LeaveCriticalSection(&eventLock); + + return hr; +} + +HRESULT DeviceManager::CreateDeviceEventManager(ifc_deviceeventmanager **eventManager) +{ + return DeviceEventManager::CreateInstance( + reinterpret_cast<DeviceEventManager**>(eventManager)); +} + +HRESULT DeviceManager::CreateSupportedCommandStore(ifc_devicesupportedcommandstore **store) +{ + return DeviceSupportedCommandStore::CreateInstance( + reinterpret_cast<DeviceSupportedCommandStore**>(store)); +} + +HRESULT DeviceManager::CreateSupportedCommandEnum(ifc_devicesupportedcommand **commands, size_t count, ifc_devicesupportedcommandenum **enumerator) +{ + return DeviceSupportedCommandEnum::CreateInstance(commands, count, + reinterpret_cast<DeviceSupportedCommandEnum**>(enumerator)); +} + +HRESULT DeviceManager::CreateIconStore(ifc_deviceiconstore **store) +{ + return DeviceIconStore::CreateInstance( + reinterpret_cast<DeviceIconStore**>(store)); +} + +HRESULT DeviceManager::CreateType(const char *name, ifc_devicetype **type) +{ + return DeviceType::CreateInstance(name, reinterpret_cast<DeviceType**>(type)); +} + +HRESULT DeviceManager::CreateCommand(const char *name, ifc_devicecommand **command) +{ + return DeviceCommand::CreateInstance(name, reinterpret_cast<DeviceCommand**>(command)); + +} + +HRESULT DeviceManager::CreateConnection(const char *name, ifc_deviceconnection **connection) +{ + return DeviceConnection::CreateInstance(name, reinterpret_cast<DeviceConnection**>(connection)); +} + +void +DeviceManager::ObjectAddedCallback(DeviceObjectStore *store, ifc_deviceobject *object, void *userData) +{ + DeviceManager *manager; + manager = (DeviceManager*)userData; + + if (NULL == manager) + return; + + if (store == &manager->typeStore) + manager->EventTypeAdded((ifc_devicetype*)object); + else if (store == &manager->connectionStore) + manager->EventConnectionAdded((ifc_deviceconnection*)object); + else if (store == &manager->commandStore) + manager->EventCommandAdded((ifc_devicecommand*)object); + else if (store == &manager->deviceStore) + manager->EventDeviceAdded((ifc_device*)object); +} + +void +DeviceManager::ObjectRemovedCallback(DeviceObjectStore *store, ifc_deviceobject *object, void *userData) +{ + DeviceManager *manager; + manager = (DeviceManager*)userData; + + if (NULL == manager) + return; + + if (store == &manager->typeStore) + manager->EventTypeRemoved((ifc_devicetype*)object); + else if (store == &manager->connectionStore) + manager->EventConnectionRemoved((ifc_deviceconnection*)object); + else if (store == &manager->commandStore) + manager->EventCommandRemoved((ifc_devicecommand*)object); + else if (store == &manager->deviceStore) + manager->EventDeviceRemoved((ifc_device*)object); +} + + +void DeviceManager::EventTypeAdded(ifc_devicetype *type) +{ + EnterCriticalSection(&eventLock); + + size_t index = eventList.size(); + while(index--) + { + ifc_devicemanagerevent *handler = eventList[index]; + handler->TypeAdded((api_devicemanager*)this, type); + } + + LeaveCriticalSection(&eventLock); +} + +void DeviceManager::EventTypeRemoved(ifc_devicetype *type) +{ + EnterCriticalSection(&eventLock); + + size_t index = eventList.size(); + while(index--) + { + ifc_devicemanagerevent *handler = eventList[index]; + handler->TypeRemoved((api_devicemanager*)this, type); + } + + LeaveCriticalSection(&eventLock); +} + +void DeviceManager::EventConnectionAdded(ifc_deviceconnection *connection) +{ + EnterCriticalSection(&eventLock); + + size_t index = eventList.size(); + while(index--) + { + ifc_devicemanagerevent *handler = eventList[index]; + handler->ConnectionAdded((api_devicemanager*)this, connection); + } + + LeaveCriticalSection(&eventLock); +} + +void DeviceManager::EventConnectionRemoved(ifc_deviceconnection *connection) +{ + EnterCriticalSection(&eventLock); + + size_t index = eventList.size(); + while(index--) + { + ifc_devicemanagerevent *handler = eventList[index]; + handler->ConnectionRemoved((api_devicemanager*)this, connection); + } + + LeaveCriticalSection(&eventLock); +} + +void DeviceManager::EventCommandAdded(ifc_devicecommand *command) +{ + EnterCriticalSection(&eventLock); + + size_t index = eventList.size(); + while(index--) + { + ifc_devicemanagerevent *handler = eventList[index]; + handler->CommandAdded((api_devicemanager*)this, command); + } + + LeaveCriticalSection(&eventLock); +} + +void DeviceManager::EventCommandRemoved(ifc_devicecommand *command) +{ + EnterCriticalSection(&eventLock); + + size_t index = eventList.size(); + while(index--) + { + ifc_devicemanagerevent *handler = eventList[index]; + handler->CommandRemoved((api_devicemanager*)this, command); + } + + LeaveCriticalSection(&eventLock); +} + +void DeviceManager::EventDeviceAdded(ifc_device *device) +{ + EnterCriticalSection(&eventLock); + + size_t index = eventList.size(); + while(index--) + { + ifc_devicemanagerevent *handler = eventList[index]; + handler->DeviceAdded((api_devicemanager*)this, device); + } + + LeaveCriticalSection(&eventLock); +} + +void DeviceManager::EventDeviceRemoved(ifc_device *device) +{ + EnterCriticalSection(&eventLock); + + size_t index = eventList.size(); + while(index--) + { + ifc_devicemanagerevent *handler = eventList[index]; + handler->DeviceRemoved((api_devicemanager*)this, device); + } + + LeaveCriticalSection(&eventLock); +} + +void DeviceManager::EventDiscoveryStarted() +{ + EnterCriticalSection(&eventLock); + + size_t index = eventList.size(); + while(index--) + { + ifc_devicemanagerevent *handler = eventList[index]; + handler->DiscoveryStarted((api_devicemanager*)this); + } + + LeaveCriticalSection(&eventLock); +} + +void DeviceManager::EventDiscoveryFinished() +{ + EnterCriticalSection(&eventLock); + + size_t index = eventList.size(); + while(index--) + { + ifc_devicemanagerevent *handler = eventList[index]; + handler->DiscoveryFinished((api_devicemanager*)this); + } + + LeaveCriticalSection(&eventLock); +} + +#define CBCLASS DeviceManager +START_DISPATCH; +CB(ADDREF, AddRef) +CB(RELEASE, Release) +CB(QUERYINTERFACE, QueryInterface) +CB(API_TYPEREGISTER, TypeRegister) +CB(API_TYPEREGISTERINDIRECT, TypeRegisterIndirect) +CB(API_TYPEUNREGISTER, TypeUnregister) +CB(API_TYPEFIND, TypeFind) +CB(API_TYPEENUMERATE, TypeEnumerate) +CB(API_CONNECTIONREGISTER, ConnectionRegister) +CB(API_CONNECTIONREGISTERINDIRECT, ConnectionRegisterIndirect) +CB(API_CONNECTIONUNREGISTER, ConnectionUnregister) +CB(API_CONNECTIONFIND, ConnectionFind) +CB(API_CONNECTIONENUMERATE, ConnectionEnumerate) +CB(API_COMMANDREGISTER, CommandRegister) +CB(API_COMMANDREGISTERINDIRECT, CommandRegisterIndirect) +CB(API_COMMANDUNREGISTER, CommandUnregister) +CB(API_COMMANDFIND, CommandFind) +CB(API_COMMANDENUMERATE, CommandEnumerate) +CB(API_DEVICEREGISTER, DeviceRegister) +CB(API_DEVICEUNREGISTER, DeviceUnregister) +CB(API_DEVICEFIND, DeviceFind) +CB(API_DEVICEENUMERATE, DeviceEnumerate) +CB(API_ISDISCOVERYACTIVE, IsDiscoveryActive) +CB(API_BEGINDISCOVERY, BeginDiscovery) +CB(API_CANCELDISCOVERY, CancelDiscovery) +CB(API_REGISTERPROVIDER, RegisterProvider) +CB(API_UNREGISTERPROVIDER, UnregisterProvider) +CB(API_SETPROVIDERACTIVE, SetProviderActive) +CB(API_ADVISE, Advise) +CB(API_UNADVISE, Unadvise) +CB(API_CREATEDEVICEEVENTMANAGER, CreateDeviceEventManager) +CB(API_CREATESUPPORTEDCOMMANDSTORE, CreateSupportedCommandStore) +CB(API_CREATESUPPORTEDCOMMANDENUM, CreateSupportedCommandEnum) +CB(API_CREATEICONSTORE, CreateIconStore) +CB(API_CREATETYPE, CreateType) +CB(API_CREATECOMMAND, CreateCommand) +CB(API_CREATECONNECTION, CreateConnection) +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file |