Пример #1
0
void TutorialApp::update()
{
	/*
	 * An event handler is a good place to add functionality 
	 * to your UiTree. Think of it as a many application for 
	 * your node. In this case, we've added some logic to the 
	 * event handler to record the ID of any node that needs 
	 * to be removed.
	 */
	uint64_t removeId = mEventHandler.getRemoveId();

	/*
	 * When removing a node, be sure to also remove any 
	 * external data it is using to save on resources.
	 */
	if ( removeId > 0 && mUiTree.removeChild( removeId ) ) {
		if ( mIdBatchMap.find( removeId ) != mIdBatchMap.end() ) {
			mIdBatchMap.erase( removeId );
		}
		makeNode();
	}
	mEventHandler.setRemoveId( 0 );

	const float e = (float)getElapsedSeconds();

	/*
	 * If you ever need a flat list of all nodes in your UiTree, 
	 * run a query which returns true.
	 */ 
	list<UiTree*> nodes = mUiTree.query( []( const UiTree& node )
	{
		return true;
	} );

	const vec2 c = getWindowCenter();

	/*
	 * Although there is an update event in the UiTree, it is 
	 * best to keep the quantity of update signals to a minimum.
	 * If you want to organize your code a bit, consider writing 
	 * "controller" nodes. That is, create a node's event handler 
	 * with some more sophisticated callbacks. If you have hundreds 
	 * or thousands of nodes that all have update or mouse events, 
	 * for example, you might get better performance by hit testing 
	 * them all from a single node instead of giving them all 
	 * their own event handlers. In this example, we update the tree 
	 * from the main application's update loop.
	 */
	for ( UiTree* a : nodes ) {
		if ( a->getParent() != nullptr ) {
			UiData& data	= a->getData();
			const float s	= data.getSpeed();
			a->setTranslate( c + vec2( cos( e * s ), sin( e * s ) ) * data.getDistance() );

			float d0 = numeric_limits<float>::max();
			for ( UiTree* b : nodes ) {
				if ( a != b && b->getScale().x > a->getScale().x ) {
					const float d1 = glm::distance( a->getTranslate(), b->getTranslate() );
					if ( d1 < d0 ) {
						d0 = d1;
						a->setParent( b );
					}
				}
			}
		}
	}
}