void BLooper::SetCommonFilterList(BList* filters) { AssertLocked(); BMessageFilter* filter; if (filters) { // Check for ownership issues - a filter can only have one owner for (int32 i = 0; i < filters->CountItems(); ++i) { filter = (BMessageFilter*)filters->ItemAt(i); if (filter->Looper()) { debugger("A MessageFilter can only be used once."); return; } } } if (fCommonFilters) { for (int32 i = 0; i < fCommonFilters->CountItems(); ++i) { delete (BMessageFilter*)fCommonFilters->ItemAt(i); } delete fCommonFilters; fCommonFilters = NULL; } // Per the BeBook, we take ownership of the list fCommonFilters = filters; if (fCommonFilters) { for (int32 i = 0; i < fCommonFilters->CountItems(); ++i) { filter = (BMessageFilter*)fCommonFilters->ItemAt(i); filter->SetLooper(this); } } }
void BHandler::SetFilterList(BList* filters) { BLooper* looper = fLooper; if (looper != NULL && !looper->IsLocked()) { debugger("Owning Looper must be locked before calling SetFilterList"); return; } /** @note I would like to use BObjectList internally, but this function is spec'd such that fFilters would get deleted and then assigned 'filters', which would obviously mess this up. Wondering if anyone ever assigns a list of filters and then checks against FilterList() to see if they are the same. */ // TODO: Explore issues with using BObjectList if (fFilters != NULL) { fFilters->DoForEach(FilterDeleter); delete fFilters; } fFilters = filters; if (fFilters) { for (int32 i = 0; i < fFilters->CountItems(); ++i) { BMessageFilter* filter = static_cast<BMessageFilter*>(fFilters->ItemAt(i)); if (filter != NULL) filter->SetLooper(looper); } } }
BHandler* BLooper::_ApplyFilters(BList* list, BMessage* message, BHandler* target) { // This is where the action is! // check the parameters if (list == NULL || message == NULL) return target; // for each filter in the provided list BMessageFilter* filter = NULL; for (int32 i = 0; i < list->CountItems(); ++i) { filter = (BMessageFilter*)list->ItemAt(i); // check command conditions if (filter->FiltersAnyCommand() || filter->Command() == message->what) { // check delivery conditions message_delivery delivery = filter->MessageDelivery(); bool dropped = message->WasDropped(); if (delivery == B_ANY_DELIVERY || (delivery == B_DROPPED_DELIVERY && dropped) || (delivery == B_PROGRAMMED_DELIVERY && !dropped)) { // check source conditions message_source source = filter->MessageSource(); bool remote = message->IsSourceRemote(); if (source == B_ANY_SOURCE || (source == B_REMOTE_SOURCE && remote) || (source == B_LOCAL_SOURCE && !remote)) { // Are we using an "external" function? filter_result result; filter_hook filterFunction = filter->FilterFunction(); if (filterFunction != NULL) result = filterFunction(message, &target, filter); else result = filter->Filter(message, &target); // Is further processing allowed? if (result == B_SKIP_MESSAGE) { // no, time to bail out return NULL; } } } } } return target; }