Beispiel #1
0
/*************************************************************
* @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() ;
	}
}
Beispiel #2
0
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);
	}
}
Beispiel #3
0
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;
	}
}
Beispiel #4
0
/*************************************************************
* @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) ;
}
void MessageService::publish(std::string message, StringMap params) {
    comsSem.wait();
    
    SubscriptionMap::const_iterator got = subscriptions.find(message);
    
    if(got != subscriptions.end()) {
        CallbackList messageList = got->second;
        
        for(CallbackList::size_type i = 0; i < messageList.size(); i++) {
            messageList[i](params);
        }
    }
    
    comsSem.signal();
}
Beispiel #6
0
void
signal_emit(Signal *sig, ...) {
	va_list args;
	va_start(args, sig);

	int res;
	CallbackList *iter = sig->callbacks;
	while(iter != NULL) {
		res = iter->data(iter->user_arg, args);
		iter = iter->next;
	}

	va_end(args); 

	sig->emit_counter++;
}
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();
}
Beispiel #8
0
/*************************************************************
* @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) ;
}
Beispiel #9
0
static inline
void clear_all()
{
	routine_tid = 0;
	cmdSRSPCallbackPtr.reset( NULL );
	cmdCbTmpList.clear();
	callbackParserTable.clear();
	genCbList.clear();
	genCbTmpList.clear();
	genBroadcastCbList.clear();
	thisDev.reset( NULL );

	zigbeeSrvSet.clear();
	zigbeeDevSet.clear();
//	zigbeeCandDevSet.clear();
}
Beispiel #10
0
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);
}
bool CallbackMainDispatcher::unregisterCallback(int callbackId) {
	CallbackList newEventList;
	{
		TelldusCore::MutexLocker locker(&d->mutex);
		for(CallbackList::iterator callback_it = d->callbackList.begin(); callback_it != d->callbackList.end(); ++callback_it) {
			if ( (*callback_it)->id != callbackId ) {
				continue;
			}
			newEventList.splice(newEventList.begin(), d->callbackList, callback_it);
			break;
		}
	}
	if (newEventList.size()) {
		CallbackList::iterator it = newEventList.begin();
		{ //Lock and unlock to make sure no one else uses the object
			TelldusCore::MutexLocker locker( &(*it)->mutex );
		}
		delete (*it);
		newEventList.erase(it);
		return true;
	}
	return false;
}
Beispiel #12
0
/*************************************************************
* @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 ;
}