РЕЗЮМЕ: Клиент находится на сервере Teamspeak с другими пользователями. Когда другие пользователи начинают говорить, этот плагин запускает функцию setSpeakerPosition()
для пользователя каждые 500 мс, пока они не перестают говорить. Он должен сделать это снова, если они снова начнут говорить.
ПРОБЛЕМА: Если я просто делаю .reset(new boost::thread(...))
каждый раз, когда они начинают говорить, это, кажется, перезаписывает существующий поток (если они говорили ранее) и приводит к сбою. Я считаю, что мне нужно «оживить» существующий поток или уничтожить его должным образом.
// Create an array like: speakingThreads[client_id] = array(bIsSpeaking, ptrThread)
typedef boost::shared_ptr<boost::thread> SmartThread;
map<anyID, pair<bool, SmartThread>> speakingThreads;
// Called when someone starts or stops talking
void ts3plugin_onTalkStatusChangeEvent(uint64 serverConnectionHandlerID, int status, int isReceivedWhisper, anyID clientID) {
// Get my client id
anyID myID;
ts3Functions.getClientID(serverConnectionHandlerID, &myID);
// If someone else starts talking
if(clientID != myID && status == STATUS_TALKING) {
// Set client to 'is speaking' (allows thread loop to run)
speakingThreads[clientID].first = true;
// If this is the first time they have spoken, start a thread
if(speakingThreads[clientID].second == NULL) {
// Create thread to keep updating speaker position while he's speaking
speakingThreads[clientID].second.reset(new boost::thread(speakerActiveThread, serverConnectionHandlerID, clientID));
_log("Starting Thread", 0);
}
// Or if they've spoken before, revive the thread
else {
speakingThreads[clientID].second->speakerActiveThread(serverConnectionHandlerID, clientID); // error C2039: 'speakerActiveThread' : is not a member of 'boost::thread'
_log("Reviving Thread", 0);
}
}
// If someone else stops talking
else if(clientID != myID && status == STATUS_NOT_TALKING) {
if(speakingThreads.find(clientID) != speakingThreads.end()) {
// Disable thread loop for the speaker to stop updating his position
speakingThreads[clientID].first = false;
_log("Interrupted Speaking Thread", 0);
}
}
}
// Thread run when someone starts speaking, loops until they finish speaking
void speakerActiveThread(uint64 serverConnectionHandlerID, anyID clientID) {
// While client 'is speaking'
while(speakingThreads[clientID].first) {
if(setSpeakerPosition(serverConnectionHandlerID, clientID) != ERROR_ok) {
_log("ERROR Setting Speaker Position", 1);
}
_log("Set Speaker Position", 0);
Sleep(UPDATE_SPEAKER_MS); // 500
}
}