bool spoutSenderNames::GetSenderSet(std::set<std::string>& SenderNames) { std::set<std::string>::iterator iter; char* pBuf = NULL; // Open or create m_sendernames if (!CreateSenderSet()) { return false; } pBuf = m_senderNames.Lock(); if (!pBuf) { return false; } // The data has been stored with 256 bytes reserved for each Sender name // and nothing will have changed with the map yet if(pBuf[0] == 0) { // no senders yet m_senderNames.Unlock(); return true; } // Read back from the mapped memory buffer and rebuild the set that was passed in // The set will then contain the senders currently in the memory map // and allow for any that have been added or deleted readSenderSetFromBuffer(pBuf, SenderNames, m_MaxSenders); m_senderNames.Unlock(); return true; } // end GetSenderSet
// Functions to set or get the active Sender name // The "active" Sender is the one of the multiple Senders // that is top of the list or is the one selected by the user from this list. // This active Sender information is saved in a separated shared // memory from other Senders, identified by the name "ActiveSenderName" // so it can be recalled at any time by clients if the user // has selected a required Sender from a dialog or executable. // The dialog or executable sets the info of the selected Sender // into the ActiveSender shared memory so the clients can picks it up. // !!! The active Sender has to be a member of the Sender list !!! bool spoutSenderNames::SetActiveSender(const char *Sendername) { std::set<std::string> SenderNames; if (!CreateSenderSet()) { return false; } // Keep the sender set locked for this entire operation if (!m_senderNames.Lock()) { return false; } // Get the current list to check whether the passed name is in it if(GetSenderSet(SenderNames)) { if(SenderNames.find(Sendername) != SenderNames.end() ) { if(setActiveSenderName(Sendername)) { // set the active Sender name to shared memory m_senderNames.Unlock(); return true; } } } m_senderNames.Unlock(); return false; } // end SetActiveSender
// TODO - use pointer from initial map creation bool spoutSenderNames::GetSenderSet(std::set<string>& SenderNames) { string namestring; // local string to retrieve names std::set<string>::iterator iter; if (!CreateSenderSet()) { return false; } char* pBuf = m_senderNames.Lock(); if (!pBuf) { return false; } // The data has been stored with 256 bytes reserved for each Sender name // and nothing will have changed with the map yet // MB - Use alloca, we know the data is small enough to fit on the stack char *buffer = (char *)_alloca(MaxSenders*SpoutMaxSenderNameLen*sizeof(unsigned char)); // copy the shared memory to the local buffer memcpy ( (void *)buffer, (void *)pBuf, MaxSenders*SpoutMaxSenderNameLen ); m_senderNames.Unlock(); // Read back from the buffer and rebuild the set readSenderSetFromBuffer(buffer, SenderNames); return true; } // end GetSenderSet
// // Removes a Sender from the set of Sender names // bool spoutSenderNames::ReleaseSenderName(const char* Sendername) { std::set<std::string> SenderNames; std::string namestring; char name[SpoutMaxSenderNameLen]; // Create the shared memory for the sender name set if it does not exist if(!CreateSenderSet()) return false; char *pBuf = m_senderNames.Lock(); if (!pBuf) return false; namestring = Sendername; auto foundSender = m_senders->find(namestring); if (foundSender != m_senders->end()) { delete foundSender->second; m_senders->erase(namestring); } readSenderSetFromBuffer(pBuf, SenderNames, m_MaxSenders); // Discovered that the project properties had been set to CLI // Properties -> General -> Common Language Runtime Support // and this caused the set "find" function not to work. // It also disabled intellisense. // Get the current map to update the list if(SenderNames.find(Sendername) != SenderNames.end() ) { SenderNames.erase(Sendername); // erase the matching Sender writeBufferFromSenderSet(SenderNames, pBuf, m_MaxSenders); // Is there a set left ? if(SenderNames.size() > 0) { // This should be OK because the user selects the active sender // Was it the active sender ? if( (getActiveSenderName(name) && strcmp(name, Sendername) == 0) || SenderNames.size() == 1) { // It was, so choose the first in the list std::set<std::string>::iterator iter = SenderNames.begin(); namestring = *iter; strcpy_s(name, namestring.c_str()); // Set it as the active sender setActiveSenderName(name); } } m_senderNames.Unlock(); return true; } m_senderNames.Unlock(); return false; // Sender name not in the set or no set in shared mempry } // end RemoveSender
int spoutSenderNames::GetSenderCount() { std::set<string> SenderSet; std::set<string>::iterator iter; string namestring; char name[SpoutMaxSenderNameLen]; SharedTextureInfo info; // Create the shared memory for the sender name set if it does not exist if(!CreateSenderSet()) { return 0; } // Doing multiple operations on the sender list, keep it locked if (!m_senderNames.Lock()) { return 0; } // get the name list in shared memory into a local list GetSenderNames(&SenderSet); // Now we have a local set of names // 27.12.13 - noted that if a Processing sketch is stopped by closing the window // all is OK and either the "stop" or "dispose" overrides work, but if STOP is used, // or the sketch is closed, neither the exit or dispose functions are called and // the sketch does not release the sender. // So here we run through again and check whether the sender exists and if it does not // release the sender from the local sender list if(SenderSet.size() > 0) { for(iter = SenderSet.begin(); iter != SenderSet.end(); iter++) { namestring = *iter; // the Sender name string strcpy_s(name, namestring.c_str()); // we have the name already, so look for it's info if(!getSharedInfo(name, &info)) { // Sender does not exist any more ReleaseSenderName(name); // release from the shared memory list } } } // Get the new set back if(GetSenderNames(&SenderSet)) { m_senderNames.Unlock(); return(SenderSet.size()); } m_senderNames.Unlock(); return 0; }
void spoutSenderNames::cleanSenderSet() { if(!CreateSenderSet()) { return; } char *pBuf = m_senderNames.Lock(); if (!pBuf) { return; } std::set<std::string> SenderNames; readSenderSetFromBuffer(pBuf, SenderNames, m_MaxSenders); bool changed = false; for (auto itr = SenderNames.begin(); itr != SenderNames.end(); ) { // It's one of ours, so thats fine if (m_senders->find(*itr) != m_senders->end()) { itr++; continue; } SpoutSharedMemory mem; // This isn't found, we clean it up if (!mem.Open((*itr).c_str())) { changed = true; SenderNames.erase(itr++); } else { ++itr; } } if (changed) { writeBufferFromSenderSet(SenderNames, pBuf, m_MaxSenders); } m_senderNames.Unlock(); }
// // ========================= // multiple Sender functions // ========================= // // Register a new Sender by adding to the list of Sender names // bool spoutSenderNames::RegisterSenderName(const char* Sendername) { std::pair<std::set<std::string>::iterator, bool> ret; std::set<std::string> SenderNames; // set of names // Create the shared memory for the sender name set if it does not exist if(!CreateSenderSet()) return false; char *pBuf = m_senderNames.Lock(); if (!pBuf) return false; // Register the sender name in the list of spout senders readSenderSetFromBuffer(pBuf, SenderNames, m_MaxSenders); // // Add the Sender name to the set of names // ret = SenderNames.insert(Sendername); if(!ret.second) { // See if there are any dangling entries that aren't valid anymore cleanSenderSet(); readSenderSetFromBuffer(pBuf, SenderNames, m_MaxSenders); ret = SenderNames.insert(Sendername); } if(ret.second) { // write the new map to shared memory writeBufferFromSenderSet(SenderNames, pBuf, m_MaxSenders); // Set as the active Sender if it is the first one registered // Thereafter the user can select an active Sender using SpoutPanel or SpoutSenders m_activeSender.Create("ActiveSenderName", SpoutMaxSenderNameLen); // The active sender is the one selected by the user // or the last one opened by the user, so don't limit to the first sender // Set the current sender name as active SetActiveSender(Sendername); } m_senderNames.Unlock(); return ret.second; }