#include using namespace std; MWMap::MWMap(bool trace, const shared_ptr& logger) : _trace(trace), _logger(logger) { } void MWMap::reserve(const string& name) { lock_guard sync(_mutex); if(_reserved.find(name) != _reserved.end() || _members.find(name) != _members.end()) { throw runtime_error("The name " + name + " is already in use."); } _reserved.insert(name); } void MWMap::unreserve(const string& name) { lock_guard sync(_mutex); _reserved.erase(name); } void MWMap::join(const string& name, const shared_ptr& callback) { lock_guard sync(_mutex); long long timestamp = chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count(); _reserved.erase(name); Ice::StringSeq names; for(const auto& q : _members) { names.push_back(q.first); } callback->init(move(names)); _members[name] = callback; auto e = make_shared(timestamp, name); for(const auto& q: _members) { q.second->join(e); } if(_trace) { Ice::Trace out(_logger, "info"); out << "User '" << name << "' joined the MW Map."; } } void MWMap::leave(const string& name) { lock_guard sync(_mutex); long long timestamp = chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count(); _members.erase(name); auto e = make_shared(timestamp, name); for(const auto& q: _members) { q.second->leave(e); } if(_trace) { Ice::Trace out(_logger, "info"); out << "User '" << name << "' left the MWMap."; } } Ice::Long MWMap::send(const string& name, string message) { lock_guard sync(_mutex); long long timestamp = chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count(); auto e = make_shared(timestamp, name, message); for(const auto& q: _members) { q.second->send(e); } if(_trace) { Ice::Trace out(_logger, "info"); out << name << ": " << message; } return timestamp; }