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);
}