void ObservableLooper::MessageReceived( BMessage* message) { // PRINT(( // "### ObservableLooper::MessageReceived()\n")); // message->PrintToStream(); switch(message->what) { case M_ADD_OBSERVER: _handleAddObserver(message); break; case M_REMOVE_OBSERVER: _handleRemoveObserver(message); break; case M_KILL_OBSERVABLE: releaseComplete(); BLooper::Quit(); break; default: _inherited::MessageReceived(message); } }
void ObservableHandler::MessageReceived( BMessage* message) { // PRINT(( // "### ObservableHandler::MessageReceived()\n")); // message->PrintToStream(); switch(message->what) { case M_ADD_OBSERVER: _handleAddObserver(message); break; case M_REMOVE_OBSERVER: _handleRemoveObserver(message); break; case M_KILL_OBSERVABLE: // +++++ this should be an optional feature releaseComplete(); delete this; // BOOM! break; default: _inherited::MessageReceived(message); } }
void ObservableLooper::Quit() { ASSERT(IsLocked()); if(QuitRequested()) { releaseComplete(); _inherited::Quit(); } else Unlock(); }
void ObservableLooper::_handleRemoveObserver( BMessage* message) { // PRINT(("ObservableLooper::_handleRemoveObserver():\n" // " %ld targets\n", CountTargets())); BMessage reply; BMessenger observer; status_t err = message->FindMessenger( "observer", &observer); if(err < B_OK) { PRINT(( "* ObservableLooper::_handleRemoveObserver(): no observer specified!\n")); // send reply? +++++ return; } // at this point, a reply of some sort will be sent reply.AddMessenger("target", BMessenger(this)); reply.AddMessenger("observer", observer); int32 index = IndexOfTarget(observer.Target(0)); if(index == -1) { reply.what = M_BAD_OBSERVER; } else { RemoveTarget(index); reply.what = M_OBSERVER_REMOVED; } message->SendReply(&reply); // call hook observerRemoved(observer); // time to shut down? if(m_quitting && !CountTargets()) { releaseComplete(); BLooper::Quit(); } }
void ObservableHandler::_handleRemoveObserver( BMessage* message) { #if DEBUG BLooper* l = Looper(); ASSERT(l); ASSERT(l->IsLocked()); #endif BMessage reply; BMessenger observer; status_t err = message->FindMessenger( "observer", &observer); if(err < B_OK) { PRINT(( "* ObservableHandler::_handleRemoveObserver(): no observer specified!\n")); // send reply? +++++ return; } int32 index = IndexOfTarget(observer.Target(0)); if(index == -1) { reply.what = M_BAD_OBSERVER; reply.AddMessenger("target", BMessenger(this)); reply.AddMessenger("observer", observer); message->SendReply(&reply); return; } // valid observer given; remove it & call notification hook RemoveTarget(index); observerRemoved(observer); // time to shut down? if(m_released && !CountTargets()) { releaseComplete(); delete this; // BOOM! } }
__USE_CORTEX_NAMESPACE // ---------------------------------------------------------------- // // *** deletion // ---------------------------------------------------------------- // // clients must call release() rather than deleting, // to ensure that all observers are notified of the // object's demise. if the object has already been // released, return an error. status_t ObservableHandler::release() { if(m_released) return B_NOT_ALLOWED; // PRINT(( // "ObservableHandler::release(): %ld targets\n", CountTargets())); if(!LockLooper()) { ASSERT(!"failed to lock looper"); } m_released = true; if(CountTargets()) { // notify notifyRelease(); UnlockLooper(); } else { releaseComplete(); UnlockLooper(); delete this; } return B_OK; }