void LLMotionController::pauseAllSyncedCharacters(std::vector<LLAnimPauseRequest>& avatar_pause_handles) { // Run over all motions. for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end(); ++iter) { LLMotion* motionp = *iter; AISyncServer* server = motionp->server(); if (server && !server->never_synced() && motionp->isActive()) // Skip motions that aren't synchronized at all or that are not active. { // Run over all clients of the found servers. AISyncServer::client_list_t const& clients = server->getClients(); for (AISyncServer::client_list_t::const_iterator client = clients.begin(); client != clients.end(); ++client) { LLMotion* motion = dynamic_cast<LLMotion*>(client->mClientPtr); if (!motion) { continue; } LLMotionController* controller = motion->getController(); if (controller == this) { continue; } controller->requestPause(avatar_pause_handles); } } } }
void LLMotionController::refresh_hidden(void) { mHaveVisibleSyncedMotions = !mHidden; // Run over all motions. for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end(); ++iter) { LLMotion* motionp = *iter; AISyncServer* server = motionp->server(); if (server && !server->never_synced() && motionp->isActive()) // Skip motions that aren't synchronized at all or that are not active. { bool visible_after = server->events_with_at_least_one_client_ready() & 4; if (visible_after) // Are there any synchronized motions (left) that ARE visible? { mHaveVisibleSyncedMotions = true; } } } }
//<singu> //----------------------------------------------------------------------------- // toggle_hidden() //----------------------------------------------------------------------------- void LLMotionController::toggle_hidden(void) { mHaveVisibleSyncedMotions = mHidden; // Default is false if we just became invisible (otherwise this value isn't used). mHidden = !mHidden; synceventset_t const visible = mHidden ? 0 : 4; // Run over all motions. for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end(); ++iter) { LLMotion* motionp = *iter; AISyncServer* server = motionp->server(); if (server && !server->never_synced() && motionp->isActive()) // Skip motions that aren't synchronized at all or that are not active. { bool visible_before = server->events_with_at_least_one_client_ready() & 4; server->ready(4, visible, motionp); // Mark that now we are visible or no longer visible. bool visible_after = server->events_with_at_least_one_client_ready() & 4; if (visible_after) // Are there any synchronized motions (left) that ARE visible? { mHaveVisibleSyncedMotions = true; } if (visible_before != visible_after) { // The group as a whole now might need to change whether or not it is animated. AISyncServer::client_list_t const& clients = server->getClients(); for (AISyncServer::client_list_t::const_iterator client = clients.begin(); client != clients.end(); ++client) { LLMotion* motion = dynamic_cast<LLMotion*>(client->mClientPtr); if (!motion) { continue; } LLMotionController* controller = motion->getController(); if (controller == this) { continue; } if (visible_after) { // Us becoming visible means that all synchronized avatars need to be animated again too. controller->setHaveVisibleSyncedMotions(); } else { // Us becoming hidden means that all synchronized avatars might stop animating. controller->refresh_hidden(); // It is extremely unlikely, but harmless, to call this twice on the same controller. } } } } } }
void TestsuiteClient<synckeytype>::change_state(unsigned long r) { bool change_registered = r & 1; r >>= 1; synceventset_t toggle_events = r & 15; r >>= 4; if (change_registered) { if (mRequestedRegistered && !mRequestedReady) { mRequestedRegistered = false; this->unregister_client(); } } else if (toggle_events) { mRequestedReady ^= toggle_events; mRequestedRegistered = true; this->ready(toggle_events, mRequestedReady & toggle_events); } llassert(mRequestedRegistered == is_registered()); AISyncServer* server = this->server(); if (mRequestedRegistered) { synceventset_t all_ready = synceventset_t(-1); synceventset_t any_ready = 0; int nr = 0; for (int cl = 0; cl < number_of_clients_per_syncgroup; ++cl) { switch ((synckeytype & 0xff)) { case syncgroup_test1: { if (client1ap[cl].server() == server) { if (client1ap[cl].getRequestedRegistered()) { ++nr; all_ready &= client1ap[cl].getRequestedReady(); any_ready |= client1ap[cl].getRequestedReady(); } } if (client1bp[cl].server() == server) { if (client1bp[cl].getRequestedRegistered()) { ++nr; all_ready &= client1bp[cl].getRequestedReady(); any_ready |= client1bp[cl].getRequestedReady(); } } break; } case syncgroup_test2: { if (client2ap[cl].server() == server) { if (client2ap[cl].getRequestedRegistered()) { ++nr; all_ready &= client2ap[cl].getRequestedReady(); any_ready |= client2ap[cl].getRequestedReady(); } } if (client2bp[cl].server() == server) { if (client2bp[cl].getRequestedRegistered()) { ++nr; all_ready &= client2bp[cl].getRequestedReady(); any_ready |= client2bp[cl].getRequestedReady(); } } break; } } } llassert(nr == server->getClients().size()); llassert(!!(all_ready & 1) == mActualReady1); llassert(this->server()->events_with_all_clients_ready() == all_ready); llassert(this->server()->events_with_at_least_one_client_ready() == any_ready); llassert(nr == 0 || (any_ready & all_ready) == all_ready); } llassert(mRequestedReady == this->mReadyEvents); }
void AISyncServerMap::register_client(AISyncClient* client, AISyncKey* new_key) { // client must always be a new client that has to be stored somewhere. llassert(client->server() == NULL); // Obviously the client can't be ready for anything when it isn't registered yet. llassert(!client->mReadyEvents); // Find if a server with this key already exists. AISyncServer* server = NULL; for (server_list_t::iterator iter = mServers.begin(); iter != mServers.end();) { boost::intrusive_ptr<AISyncServer>& server_ptr = *iter++; // Immediately increment iter because the call to unregister_last_client will erase it. AISyncKey const& server_key(server_ptr->key()); if (server_key.is_older_than(*new_key)) // This means that the server key is expired: a new key will never match. { if (server_ptr->never_synced()) // This means that it contains one or zero clients and will never contain more. { // Get rid of this server. server_ptr->unregister_last_client(); // This will cause the server to be deleted, and erased from mServers. } continue; } if (*new_key == server_key) { server = server_ptr.get(); // mServers stores new servers in strict order of the creation time of the keys, // so once we find a server with a key that is equal, none of the remaining servers // will have expired if they were never synced and we're done with the loop. // Servers that synced might have been added later, but we don't unregister // clients from those anyway because their sync partner might still show up. break; } } if (server) { // A server already exists. // Keep the oldest key, unless this new key has a synckeytype_t that is larger! if (new_key->getkeytype() > server->key().getkeytype()) { server->swapkey(new_key); } delete new_key; } else { // Create a new server for this client. Transfers the ownership of the key allocation to the server. server = new AISyncServer(new_key); // Add it to mServers, before the last server that is younger then the new key. server_list_t::iterator where = mServers.end(); // Insert the new server before 'where', server_list_t::iterator new_where = where; while (where != mServers.begin()) // unless there exists a server before that { --new_where; if (new_key->getCreationTime() > (*new_where)->key().getCreationTime()) // and the new key is not younger then that, { break; } where = new_where; // then insert it before that element (etc). } // This method causes a single call to intrusive_ptr_add_ref and none to intrusive_ptr_release. server_ptr_t server_ptr = server; mServers.insert(where, server_ptr_t())->swap(server_ptr); } // Add the client to the server. server->add(client); }