sessions dynamically removed

This commit is contained in:
Hane 2024-02-03 20:32:49 +01:00
commit 5211b70669
9 changed files with 114 additions and 73 deletions

View file

@ -47,7 +47,7 @@ HRESULT EndpointNewSessionCallback::OnSessionCreated(IAudioSessionControl *NewSe
sessionControl->AddRef(); sessionControl->AddRef();
//sessionControl->QueryInterface(__uuidof(ISimpleAudioVolume), (void**)&sessionVolume); //sessionControl->QueryInterface(__uuidof(ISimpleAudioVolume), (void**)&sessionVolume);
Session* newSession = new Session(this->eph->getEndpoint(), sessionControl); Session* newSession = new Session(this->eph->getEndpoint(), sessionControl);
eph->addSession(newSession); eph->addSessionSendFront(newSession);
} }
if (result == S_OK) if (result == S_OK)
@ -602,7 +602,6 @@ void Overseer::reloadEndpoints(Flows flow) {
if(deviceCollection->Item(i, &temp) != 0) { log_debugcpp("si"); }; if(deviceCollection->Item(i, &temp) != 0) { log_debugcpp("si"); };
Endpoint *endpoint = new Endpoint(temp, i); Endpoint *endpoint = new Endpoint(temp, i);
//endpoint->setIndex(i);
if (flow == Flows::FLOW_PLAYBACK) if (flow == Flows::FLOW_PLAYBACK)
this->playbackDevices.push_back(endpoint); this->playbackDevices.push_back(endpoint);
else else

View file

@ -71,57 +71,26 @@ HRESULT SessionStateCallback::OnGroupingParamChanged(LPCGUID NewGroupingParam, L
} }
HRESULT SessionStateCallback::OnStateChanged(AudioSessionState NewState) { HRESULT SessionStateCallback::OnStateChanged(AudioSessionState NewState) {
/* enum _AudioSessionState { SessionState newState;// = sh->getState();
* AudioSessionStateInactive, switch (NewState) {
* AudioSessionStateActive, case AudioSessionStateActive:
* AudioSessionStateExpired newState = SessionState::ACTIVE;
* } AudioSessionState; */ break;
/* case AudioSessionStateInactive:
* char *pszState = "?????"; newState = SessionState::INACTIVE;
* break;
* switch (NewState) case AudioSessionStateExpired:
* { newState = SessionState::EXPIRED;
* case AudioSessionStateActive: break;
* pszState = "active"; }
* break;
* case AudioSessionStateInactive: sh->reviseSessionShowing(newState);
* pszState = "inactive";
* break;
* }
* printf("New session state = %s\n", pszState);
*/
return S_OK; return S_OK;
} }
HRESULT SessionStateCallback::OnSessionDisconnected(AudioSessionDisconnectReason DisconnectReason) { HRESULT SessionStateCallback::OnSessionDisconnected(AudioSessionDisconnectReason DisconnectReason) {
/* sh->setState(SessionState::DISCONNECTED);
* char *pszReason = "?????"; sh->reviseSessionShowing(SessionState::DISCONNECTED);
*
* switch (DisconnectReason)
* {
* case DisconnectReasonDeviceRemoval:
* pszReason = "device removed";
* break;
* case DisconnectReasonServerShutdown:
* pszReason = "server shut down";
* break;
* case DisconnectReasonFormatChanged:
* pszReason = "format changed";
* break;
* case DisconnectReasonSessionLogoff:
* pszReason = "user logged off";
* break;
* case DisconnectReasonSessionDisconnected:
* pszReason = "session disconnected";
* break;
* case DisconnectReasonExclusiveModeOverride:
* pszReason = "exclusive-mode override";
* break;
* }
* printf("Audio session disconnected (reason: %s)\n",
* pszReason);
*/
return S_OK; return S_OK;
} }

View file

@ -153,6 +153,10 @@ void EndpointHandler::setAddSessionWidgetFunction(std::function<void(SessionHand
this->addSessionWidget = addSessionWidget; this->addSessionWidget = addSessionWidget;
} }
void EndpointHandler::setRemoveSessionWidgetFunction(std::function<void(SessionHandler*)> removeSessionWidget) {
this->removeSessionWidget = removeSessionWidget;
}
/* sessions */ /* sessions */
size_t EndpointHandler::getSessionCount() { size_t EndpointHandler::getSessionCount() {
return ep->getSessionCount(); return ep->getSessionCount();
@ -170,7 +174,7 @@ Endpoint* EndpointHandler::getEndpoint() {
return this->ep; return this->ep;
} }
void EndpointHandler::addSession(Session* session) { void EndpointHandler::addSessionSendFront(Session* session) {
ep->addSession(session); ep->addSession(session);
SessionHandler* sessionHandler = new SessionHandler(this, session, (getSessionCount() - 1)); SessionHandler* sessionHandler = new SessionHandler(this, session, (getSessionCount() - 1));
@ -178,6 +182,14 @@ void EndpointHandler::addSession(Session* session) {
this->addSessionWidget(sessionHandler); this->addSessionWidget(sessionHandler);
} }
void EndpointHandler::sendSessionToFront(SessionHandler* sh) {
this->addSessionWidget(sh);
}
void EndpointHandler::removeSessionFromFront(SessionHandler* sh) {
this->removeSessionWidget(sh);
}
EndpointHandler::~EndpointHandler() { EndpointHandler::~EndpointHandler() {
ep->removeVolumeCallback(epc); ep->removeVolumeCallback(epc);
ep->unregisterNewSessionNotification(ensc); ep->unregisterNewSessionNotification(ensc);

View file

@ -66,8 +66,11 @@ public:
Endpoint* getEndpoint(); Endpoint* getEndpoint();
/*Session*/ /*Session*/
void addSession(Session* session); void addSessionSendFront(Session* session);
void setAddSessionWidgetFunction(std::function<void(SessionHandler*)> addSessionWidget); void setAddSessionWidgetFunction(std::function<void(SessionHandler*)> addSessionWidget);
void setRemoveSessionWidgetFunction(std::function<void(SessionHandler*)> removeSessionWidget);
void sendSessionToFront(SessionHandler* sh);
void removeSessionFromFront(SessionHandler* sh);
~EndpointHandler(); ~EndpointHandler();
private: private:
@ -86,6 +89,7 @@ private:
EndpointNewSessionCallback* ensc; EndpointNewSessionCallback* ensc;
std::vector<SessionHandler*> sessionHandlers; std::vector<SessionHandler*> sessionHandlers;
std::function<void(SessionHandler*)> addSessionWidget; std::function<void(SessionHandler*)> addSessionWidget;
std::function<void(SessionHandler*)> removeSessionWidget;
//QSlider *slidy; //QSlider *slidy;
}; };

View file

@ -36,6 +36,44 @@ bool SessionHandler::getMute(){
return session->getMute(); return session->getMute();
} }
void SessionHandler::setFrontIndex(uint64_t frontIdx) {
this->frontIdx = frontIdx;
}
uint64_t SessionHandler::getFrontIndex() {
return frontIdx;
}
SessionVolumeInfo* SessionHandler::getVolumeInfo() { SessionVolumeInfo* SessionHandler::getVolumeInfo() {
return &svi; return &svi;
} }
SessionState SessionHandler::getState() {
return session->getState();
}
void SessionHandler::setState(SessionState state) {
session->setState(state);
}
void SessionHandler::reviseSessionShowing(SessionState state) {
SessionState currentState = this->getState();
switch (currentState) {
case SessionState::ACTIVE:
case SessionState::INACTIVE:
if (state == SessionState::EXPIRED) {
eph->removeSessionFromFront(this);
}
break;
case SessionState::EXPIRED:
if (state == SessionState::ACTIVE || INACTIVE) {
eph->sendSessionToFront(this);
}
break;
case SessionState::DISCONNECTED:
if (frontIdx != INT_MAX)
eph->removeSessionFromFront(this);
break;
}
}

View file

@ -24,7 +24,12 @@ class SessionHandler {
float getVolume(int channel); float getVolume(int channel);
void setMute(NGuid guid, bool muted); void setMute(NGuid guid, bool muted);
bool getMute(); bool getMute();
void setFrontIndex(uint64_t frontIdx);
SessionState getState();
void setState(SessionState state);
uint64_t getFrontIndex();
std::wstring getName(); std::wstring getName();
void reviseSessionShowing(SessionState state);
SessionVolumeInfo* getVolumeInfo(); SessionVolumeInfo* getVolumeInfo();
private: private:
@ -33,5 +38,5 @@ class SessionHandler {
Session* session; Session* session;
SessionStateCallback* ssc; SessionStateCallback* ssc;
size_t idx; size_t idx;
uint64_t frontIdx = INT_MAX;
}; };

View file

@ -39,10 +39,11 @@ enum EndpointState {
}; };
enum SessionState { enum SessionState {
ACTIVE = (1 << 0), ACTIVE = (1 << 0),
INACTIVE = (1 << 1), INACTIVE = (1 << 1),
EXPIRED = (1 << 2), EXPIRED = (1 << 2),
ALL = 0x07 DISCONNECTED = (1 << 3),
ALL = 0x0F
}; };
enum Flows { enum Flows {

View file

@ -95,6 +95,11 @@ void SessionWidget::updateMainVolume(int newValue){
this->sh->setVolume(osh->getGuid(), AudioChannel::CHANNEL_MAIN, newValue); this->sh->setVolume(osh->getGuid(), AudioChannel::CHANNEL_MAIN, newValue);
} }
SessionWidget::~SessionWidget() {
volumePoller->stop();
delete volumePoller;
}
EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *parent) : QWidget(parent){ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *parent) : QWidget(parent){
//todo: based on qgridlayout, name+mute should be its own widget, same with channels //todo: based on qgridlayout, name+mute should be its own widget, same with channels
row = 0; row = 0;
@ -261,12 +266,17 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
layout->addWidget(sessionWidget, row, 4); layout->addWidget(sessionWidget, row, 4);
row++; row++;
sessionWidgets.push_back(sessionWidget); sessionWidgets.push_back(sessionWidget);
eph->getSessionHandlers().at(i)->setFrontIndex(i);
} }
/* New SessionWidget callback */ /* Add/Remove SessionWidget callback */
eph->setAddSessionWidgetFunction([this](SessionHandler* sessionHandler) { eph->setAddSessionWidgetFunction([this](SessionHandler* sessionHandler) {
QCoreApplication::instance()->postEvent(this, new CustomWidgetEvent<SessionHandler*>((QEvent::Type)CustomQEvent::SessionWidgetCreated, sessionHandler)); QCoreApplication::instance()->postEvent(this, new CustomWidgetEvent<SessionHandler*>((QEvent::Type)CustomQEvent::SessionWidgetCreated, sessionHandler));
}); });
eph->setRemoveSessionWidgetFunction([this](SessionHandler* sessionHandler) {
QCoreApplication::instance()->postEvent(this, new CustomWidgetEvent<SessionHandler*>((QEvent::Type)CustomQEvent::SessionWidgetObsolete, sessionHandler));
});
//todo parent? //todo parent?
layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum), 1, 0); layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum), 1, 0);
@ -277,23 +287,34 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
} }
void EndpointWidget::addSessionWidget(CustomWidgetEvent<SessionHandler*>* ev){ void EndpointWidget::addSessionWidget(CustomWidgetEvent<SessionHandler*>* ev){
SessionWidget* sw = new SessionWidget(this->sessionWidgets.size(), ev->payload, this); uint64_t index = this->sessionWidgets.size();
SessionWidget* sw = new SessionWidget(index, ev->payload, this);
ev->payload->setFrontIndex(index);
this->layout->addWidget(sw, row, 4); this->layout->addWidget(sw, row, 4);
row++; row++;
sessionWidgets.push_back(sw); sessionWidgets.push_back(sw);
return; return;
} }
void EndpointWidget::removeSessionWidget(CustomWidgetEvent<SessionHandler*>* ev){
uint64_t i = ev->payload->getFrontIndex();
this->sessionWidgets.at(i)->setParent(nullptr);
this->layout->removeWidget(sessionWidgets.at(i));
delete sessionWidgets.at(i);
sessionWidgets.at(i) = nullptr;
ev->payload->setFrontIndex(INT_MAX);
//this->sessionWidgetsUpdateTimer->start();
return;
}
void EndpointWidget::customEvent(QEvent* ev) { void EndpointWidget::customEvent(QEvent* ev) {
if (ev->type() == (QEvent::Type)CustomQEvent::SessionWidgetCreated) { if (ev->type() == (QEvent::Type)CustomQEvent::SessionWidgetCreated) {
ev->setAccepted(true); ev->setAccepted(true);
this->addSessionWidget((CustomWidgetEvent<SessionHandler*>*) ev); this->addSessionWidget((CustomWidgetEvent<SessionHandler*>*) ev);
return;
} else if (ev->type() == (QEvent::Type)CustomQEvent::SessionWidgetObsolete) { } else if (ev->type() == (QEvent::Type)CustomQEvent::SessionWidgetObsolete) {
ev->setAccepted(true); ev->setAccepted(true);
//this->addEndpointWidget((CustomWidgetEvent<EndpointHandler*>*)ev); this->removeSessionWidget((CustomWidgetEvent<SessionHandler*>*) ev);
} }
// Make sure the rest of events are handled
QWidget::customEvent(ev); QWidget::customEvent(ev);
} }
@ -308,12 +329,10 @@ void MainWindow::customEvent(QEvent* ev) {
if (ev->type() == CustomQEvent::EndpointWidgetObsolete) { if (ev->type() == CustomQEvent::EndpointWidgetObsolete) {
ev->setAccepted(true); ev->setAccepted(true);
this->removeEndpointWidget((CustomWidgetEvent<uint64_t>*)ev); this->removeEndpointWidget((CustomWidgetEvent<uint64_t>*)ev);
return;
} else if (ev->type() == (QEvent::Type)CustomQEvent::EndpointWidgetCreated) { } else if (ev->type() == (QEvent::Type)CustomQEvent::EndpointWidgetCreated) {
ev->setAccepted(true); ev->setAccepted(true);
this->addEndpointWidget((CustomWidgetEvent<EndpointHandler*>*)ev); this->addEndpointWidget((CustomWidgetEvent<EndpointHandler*>*)ev);
} }
// Make sure the rest of events are handled
QMainWindow::customEvent(ev); QMainWindow::customEvent(ev);
} }
@ -326,15 +345,6 @@ void MainWindow::removeEndpointWidget(CustomWidgetEvent<uint64_t>* ev){
delete ews.at(i); delete ews.at(i);
ews.at(i) = nullptr; ews.at(i) = nullptr;
this->ewsUpdateTimer->start(); this->ewsUpdateTimer->start();
/*
* while ((i + 1) < ews.size()) {
* ews.at(i) = ews.at(i + 1);
* ews.at(i)->setIndex(i);
* i++;
* }
* ews.pop_back();
*/
return; return;
} }
@ -346,6 +356,7 @@ void MainWindow::addEndpointWidget(CustomWidgetEvent<EndpointHandler*>* ev){
} }
void MainWindow::reorderEndpointWidgetCollection() { void MainWindow::reorderEndpointWidgetCollection() {
/* Flatten */
size_t firstNullPosition = 0; size_t firstNullPosition = 0;
size_t ewsSize = ews.size(); size_t ewsSize = ews.size();
bool breakSorting = false; bool breakSorting = false;

View file

@ -92,7 +92,8 @@ Q_OBJECT
public: public:
SessionWidget(uint64_t idx, SessionHandler* sh, QWidget *parent /* = nullptr */); SessionWidget(uint64_t idx, SessionHandler* sh, QWidget *parent /* = nullptr */);
~SessionWidget();
public slots: public slots:
void updateMainVolume(int newValue); void updateMainVolume(int newValue);
void updateMute(int checked); void updateMute(int checked);
@ -137,6 +138,7 @@ protected:
private slots: private slots:
void addSessionWidget(CustomWidgetEvent<SessionHandler*>* ev); void addSessionWidget(CustomWidgetEvent<SessionHandler*>* ev);
void removeSessionWidget(CustomWidgetEvent<SessionHandler*>* ev);
private: private:
int row; int row;