void MessageService::subscribe(const std::string& message, Callback callback) { comsSem.wait(); SubscriptionMap::const_iterator got = subscriptions.find(message); if(got == subscriptions.end()) { CallbackList newList; newList.push_back(callback); subscriptions.insert({message, newList}); } else { CallbackList messageList = got->second; messageList.push_back(callback); } comsSem.signal(); }
void foreign_callback_add(Fl_Window *win, const char *id, ForeignCallback cb, void *data) { fl_open_display(); init_foreign_callback_atom_once(); /* remove it if exists */ foreign_callback_remove(cb); ForeignCallbackInfo fc; fc.hash_id = str_hash(id); fc.cb = cb; fc.data = data; /* FIXME: lock this somehow */ callback_list.push_back(fc); /* * Assure the same handler is not added twice since FLTK keeps internal static list of known * handlers per application instance. */ Fl::remove_handler(xevent_handler); Fl::add_handler(xevent_handler); }
/************************************************************* * @brief Register a callback for a particular type of incoming message. * * Messages are currently one of: * "call", "response" or "notify" * A call is always paired to a response (think of this as a remote function call that returns a value) * while a notify does not receive a response (think of this as a remote function call that does not return a value). * This type is stored in the "doctype" attribute of the top level SML node in the message. * NOTE: doctype's are case sensitive. * * You MUST register a callback for the "call" type of message. This callback must return a "response" message which is then * sent back over the connection. Other callbacks should not return a message. * Once the returned message has been sent it will be deleted. * * We will maintain a list of callbacks for a given type of SML document and call each in turn. * Each callback on the list will be called in turn until one returns a non-NULL response. No further callbacks * will be called for that message. This ensures that only one response is sent to a message. * * @param callback The function to call when an incoming message is received (of the right type) * @param pUserData This data is passed to the callback. It allows the callback to have some context to work in. Can be NULL. * @param pType The type of message to register for (currently one of "call", "response" or "notify"). * @param addToEnd If true add the callback to the end of the list (called last). If false, add to front where it will be called first. * * @returns 0 if successful, otherwise an error code to indicate what went wrong. *************************************************************/ void Connection::RegisterCallback(IncomingCallback callback, void* pUserData, char const* pType, bool addToEnd) { ClearError() ; if (callback == NULL || pType == NULL) { SetError(Error::kInvalidArgument) ; return ; } // Create the callback object to be stored in the map Callback* pCallback = new Callback(this, callback, pUserData) ; CallbackList* pList = NULL ; // CallbackList* pList = m_CallbackMap[pType] ; // See if we have a list of callbacks for this type yet CallbackMapIter iter = m_CallbackMap.find(pType) ; if (iter != m_CallbackMap.end()) { // If the list already exists, just grab it pList = iter->second ; } else { // Need to create the list pList = new CallbackList() ; m_CallbackMap[pType] = pList ; } // Add the callback to the list if (addToEnd) pList->push_back(pCallback) ; else pList->push_front(pCallback) ; }