void XnVFlowRouter::OpenNewSession()
{
	if (m_pActive == NULL)
	{
		return;
	}

	xnLogVerbose(XNV_NITE_MASK_CONNECT, "Router %s [0x%08x]: Connecting %s [0x%08x] as active",
		GetListenerName(), this, m_pActive->GetListenerName(), m_pActive);

	XnVMultipleHands newHands;

	XnVMultipleHands* pLocalHands;
	XnValue value;
	m_pProperties->Get(FR_PROPERTY_HANDS, value);
	pLocalHands = (XnVMultipleHands*)value;

	// Create a Multiple Hands object with the same hands, indicating all of them are new
	pLocalHands->Clone(newHands);
	newHands.ClearLists();
	for (XnVMultipleHands::Iterator iter = newHands.begin(); iter != newHands.end(); ++iter)
	{
		newHands.MarkActive((*iter)->nID);
		newHands.MarkNew((*iter)->nID);
	}

	// Send an Activation Message
	XnVActivationMessage activate(true);
	m_pActive->BaseUpdate(&activate);

	// Send the 'all-new' Point Message to to listener that's being activated
	XnVPointMessage pointMessage(&newHands);
	m_pActive->BaseUpdate(&pointMessage);
} // XnVFlowRouter::OpenNewSession
	// Create a local copy of all the hands, and set a primary for the subtree.
	void Update(const XnVMultipleHands& hands)
	{
		// Copy all the hands
		hands.Clone(m_LocalCopy);

		const XnVHandPointContext* pPrimary = hands.GetPrimaryContext();
		if (pPrimary == NULL)
		{
			// There are no points at all.
			return;
		}

		XnUInt32 nPrimary = pPrimary->nID;

		if (hands.GetContext(m_nNewPrimary) == 0)
		{
			// The secondary point we considered primary for the subtree is no longer available.
			m_nNewPrimary = 0;
		}

		// If we don't remember a secondary point as primary, or that secondary just became the primary for 
		// the entire tree, try to locate another secondary.
		if (m_nNewPrimary == 0 || m_nNewPrimary == nPrimary)
		{
			// local primary unavailable
			for (XnVMultipleHands::ConstIterator iter = hands.begin(); iter != hands.end(); ++iter)
			{
				if (iter.IsActive() && (*iter)->nID != nPrimary)
				{
					// Found a point that is active, but is not the primary. This will be the primary
					// for the subtree
					m_nNewPrimary = (*iter)->nID;
					break;
				}
			}
		}
		// Adjust the hand list with our chosen primary for the subtree
		m_LocalCopy.ReassignPrimary(m_nNewPrimary);
	}
void XnVFlowRouter::CloseOldSession()
{
	if (m_pActive == NULL)
	{
		return;
	}

	xnLogVerbose(XNV_NITE_MASK_CONNECT, "Router %s [0x%08x]: Disconnecting %s [0x%08x] as active",
		GetListenerName(), this, m_pActive->GetListenerName(), m_pActive);

	XnVMultipleHands oldHands;

	XnVMultipleHands* pLocalHands;
	XnValue value;
	m_pProperties->Get(FR_PROPERTY_HANDS, value);
	pLocalHands = (XnVMultipleHands*)value;

	// Create a Multiple Hands object with the same hands, indicating all of them are old
	pLocalHands->Clone(oldHands);
	oldHands.ClearLists();

	while (oldHands.begin() != oldHands.end())
	{
		oldHands.MarkOld((*oldHands.begin())->nID);
		oldHands.Remove((*oldHands.begin())->nID);
	}

	m_pActive->ClearQueue();

	// Send the 'all-old' Point Message to to listener that's being deactivated
	XnVPointMessage pointMessage(&oldHands);
	m_pActive->BaseUpdate(&pointMessage);

	// Send a Deactivation Message
	XnVActivationMessage deactivate(false);
	m_pActive->BaseUpdate(&deactivate);
} // XnVFlowRouter::CloseOldSession