/************************************************************* * @brief Destructor *************************************************************/ Connection::~Connection() { // Delete all callback objects CallbackMapIter mapIter = m_CallbackMap.begin() ; while (mapIter != m_CallbackMap.end()) { //char const* pType = mapIter->first ; CallbackList* pList = mapIter->second ; // Delete all callbacks in this list CallbackListIter iter = pList->begin() ; while (iter != pList->end()) { Callback* pCallback = *iter ; iter++ ; delete pCallback ; } mapIter++ ; // Delete the list itself delete pList ; } // Clear out any messages sitting on the queues while (m_IncomingMessageQueue.size() > 0) { ElementXML_Handle hMsg = m_IncomingMessageQueue.back() ; delete hMsg ; m_IncomingMessageQueue.pop() ; } }
static void do_callback_by_id(Fl_Window *win, unsigned int id) { /* FIXME: lock this somehow */ CallbackListIt it = callback_list.begin(), it_end = callback_list.end(); ForeignCallbackInfo *info; for(; it != it_end; ++it) { info = &(*it); /* call it */ if(id == info->hash_id && info->cb) info->cb(win, info->data); } }
void foreign_callback_remove(ForeignCallback cb) { if(callback_list.empty()) return; /* FIXME: lock this somehow */ CallbackListIt it = callback_list.begin(), it_end = callback_list.end(); while(it != it_end) { if((*it).cb == cb) it = callback_list.erase(it); else ++it; } }
/************************************************************* * @brief Removes a callback from the list of callbacks for a particular type of incoming message. * * @param callback The function that was previously registered. If NULL removes all callbacks for this type of message. * @param pType The type of message to unregister from (currently one of "call", "response" or "notify"). * * @returns 0 if successful, otherwise an error code to indicate what went wrong. *************************************************************/ void Connection::UnregisterCallback(IncomingCallback callback, char const* pType) { ClearError() ; if (pType == NULL) { SetError(Error::kInvalidArgument) ; return ; } // See if we have a list of callbacks for this type CallbackList* pList = GetCallbackList(pType) ; if (pList == NULL) { SetError(Error::kCallbackNotFound) ; return ; } if (callback == NULL) { // Caller asked to delete all callbacks for this type delete pList ; m_CallbackMap[pType] = NULL ; return ; } // Walk the list of callbacks, deleting any objects that // match the callback function CallbackListIter iter = pList->begin() ; bool found = false ; while (iter != pList->end()) { Callback* pCallback = *iter ; iter++ ; // See if this function matches the one we were passed // In which case, delete it. if (pCallback->getFunction() == callback) { delete pCallback ; found = true ; } } if (!found) SetError(Error::kCallbackNotFound) ; }
/************************************************************* * @brief Invoke the list of callbacks matching the doctype of the incoming message. * * @param pIncomingMsg The SML message that should be passed to the callbacks. * @returns The response message (or NULL if there is no response from any callback). *************************************************************/ ElementXML* Connection::InvokeCallbacks(ElementXML *pIncomingMsg) { ClearError() ; MessageSML *pIncomingSML = (MessageSML*)pIncomingMsg ; // MessageSML is a soarxml::ElementXML, not sml::ElementXML // Check that we were passed a valid message. if (pIncomingMsg == NULL) { SetError(Error::kInvalidArgument) ; return NULL ; } // Retrieve the type of this message char const* pType = pIncomingSML->GetDocType() ; // Check that this message has a valid doc type (all valid SML do) if (pType == NULL) { SetError(Error::kNoDocType) ; return NULL ; } // Decide if this message is a "call" which requires a "response" bool isIncomingCall = pIncomingSML->IsCall() ; // See if we have a list of callbacks for this type CallbackList* pList = GetCallbackList(pType) ; // Nobody was interested in this type of message, so we're done. if (pList == NULL) { return NULL ; } CallbackListIter iter = pList->begin() ; // Walk the list of callbacks in turn until we reach // the end or one returns a message. while (iter != pList->end()) { Callback* pCallback = *iter ; iter++ ; ElementXML* pResponse = pCallback->Invoke(pIncomingMsg) ; if (pResponse != NULL) { if (isIncomingCall) return pResponse ; // This callback was not for a call and should not return a result. // Delete the result and ignore it. pResponse->ReleaseRefOnHandle() ; pResponse = NULL ; } } // If this is a call, we must respond if (isIncomingCall) SetError(Error::kNoResponseToCall) ; // Nobody returned a response return NULL ; }