| 
									
										
										
										
											2018-10-03 22:02:46 +08:00
										 |  |  |  | // Copyright (c) 2016-2018 Easy2D - Nomango
 | 
					
						
							|  |  |  |  | // 
 | 
					
						
							|  |  |  |  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
					
						
							|  |  |  |  | // of this software and associated documentation files (the "Software"), to deal
 | 
					
						
							|  |  |  |  | // in the Software without restriction, including without limitation the rights
 | 
					
						
							|  |  |  |  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
					
						
							|  |  |  |  | // copies of the Software, and to permit persons to whom the Software is
 | 
					
						
							|  |  |  |  | // furnished to do so, subject to the following conditions:
 | 
					
						
							|  |  |  |  | // 
 | 
					
						
							|  |  |  |  | // The above copyright notice and this permission notice shall be included in
 | 
					
						
							|  |  |  |  | // all copies or substantial portions of the Software.
 | 
					
						
							|  |  |  |  | // 
 | 
					
						
							|  |  |  |  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
					
						
							|  |  |  |  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
					
						
							|  |  |  |  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
					
						
							|  |  |  |  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
					
						
							|  |  |  |  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
					
						
							|  |  |  |  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
					
						
							|  |  |  |  | // THE SOFTWARE.
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | #include "Node.h"
 | 
					
						
							|  |  |  |  | #include "Scene.h"
 | 
					
						
							|  |  |  |  | #include "Task.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | #include "Action.hpp"
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | #include "time.h"
 | 
					
						
							|  |  |  |  | #include "render.h"
 | 
					
						
							| 
									
										
										
										
											2018-10-29 15:53:45 +08:00
										 |  |  |  | #include <iterator>
 | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | namespace easy2d | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 	Node::Node() | 
					
						
							|  |  |  |  | 		: visible_(true) | 
					
						
							|  |  |  |  | 		, parent_(nullptr) | 
					
						
							|  |  |  |  | 		, hash_name_(0) | 
					
						
							|  |  |  |  | 		, clip_enabled_(false) | 
					
						
							|  |  |  |  | 		, dirty_sort_(false) | 
					
						
							|  |  |  |  | 		, dirty_transform_(false) | 
					
						
							|  |  |  |  | 		, border_(nullptr) | 
					
						
							|  |  |  |  | 		, order_(0) | 
					
						
							|  |  |  |  | 		, transform_() | 
					
						
							|  |  |  |  | 		, display_opacity_(1.f) | 
					
						
							|  |  |  |  | 		, real_opacity_(1.f) | 
					
						
							|  |  |  |  | 		, children_() | 
					
						
							|  |  |  |  | 		, actions_() | 
					
						
							|  |  |  |  | 		, tasks_() | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		, initial_matrix_() | 
					
						
							|  |  |  |  | 		, final_matrix_() | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		, border_color_(Color::Red, 0.6f) | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 	{ | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	Node::~Node() | 
					
						
							| 
									
										
										
										
											2018-09-07 23:47:21 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		SafeRelease(border_); | 
					
						
							| 
									
										
										
										
											2018-07-28 18:44:37 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::Visit() | 
					
						
							| 
									
										
										
										
											2018-06-01 17:53:56 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (!visible_) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if (clip_enabled_) | 
					
						
							| 
									
										
										
										
											2018-09-10 11:32:51 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			devices::Graphics::Instance().PushClip(final_matrix_, transform_.size); | 
					
						
							| 
									
										
										
										
											2018-09-10 11:32:51 +08:00
										 |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-06-01 17:53:56 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (children_.empty()) | 
					
						
							| 
									
										
										
										
											2018-01-30 16:45:38 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			devices::Graphics::Instance().SetTransform(final_matrix_); | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			OnDraw(); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 		else | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			// <20>ӽڵ<D3BD><DAB5><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 			if (dirty_sort_) | 
					
						
							| 
									
										
										
										
											2018-01-30 16:45:38 +08:00
										 |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 				std::sort( | 
					
						
							|  |  |  |  | 					std::begin(children_), | 
					
						
							|  |  |  |  | 					std::end(children_), | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 					[](spNode const& n1, spNode const& n2) { return n1->GetOrder() < n2->GetOrder(); } | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 				); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 				dirty_sort_ = false; | 
					
						
							| 
									
										
										
										
											2018-01-30 16:45:38 +08:00
										 |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 			size_t i; | 
					
						
							|  |  |  |  | 			for (i = 0; i < children_.size(); ++i) | 
					
						
							| 
									
										
										
										
											2018-01-30 16:45:38 +08:00
										 |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 				auto child = children_[i]; | 
					
						
							|  |  |  |  | 				// <20><><EFBFBD><EFBFBD> Order С<><D0A1><EFBFBD><EFBFBD><EFBFBD>Ľڵ<C4BD>
 | 
					
						
							|  |  |  |  | 				if (child->GetOrder() < 0) | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  | 					child->Visit(); | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 				else | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  | 					break; | 
					
						
							|  |  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2018-01-30 16:45:38 +08:00
										 |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			devices::Graphics::Instance().SetTransform(final_matrix_); | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			OnDraw(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			// <20><><EFBFBD><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD>ڵ<EFBFBD>
 | 
					
						
							|  |  |  |  | 			for (; i < children_.size(); ++i) | 
					
						
							|  |  |  |  | 				children_[i]->Visit(); | 
					
						
							| 
									
										
										
										
											2018-01-30 16:45:38 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (clip_enabled_) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			devices::Graphics::Instance().PopClip(); | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-01-30 16:45:38 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-07-28 18:44:37 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::UpdateChildren(float dt) | 
					
						
							| 
									
										
										
										
											2018-07-28 18:44:37 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (children_.empty()) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			OnUpdate(dt); | 
					
						
							|  |  |  |  | 			UpdateActions(); | 
					
						
							|  |  |  |  | 			UpdateTasks(); | 
					
						
							|  |  |  |  | 			UpdateTransform(); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 		else | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			size_t i; | 
					
						
							|  |  |  |  | 			for (i = 0; i < children_.size(); ++i) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				auto child = children_[i]; | 
					
						
							|  |  |  |  | 				// <20><><EFBFBD><EFBFBD> Order С<><D0A1><EFBFBD><EFBFBD><EFBFBD>Ľڵ<C4BD>
 | 
					
						
							|  |  |  |  | 				if (child->GetOrder() < 0) | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  | 					child->UpdateChildren(dt); | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 				else | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  | 					break; | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			OnUpdate(dt); | 
					
						
							|  |  |  |  | 			UpdateActions(); | 
					
						
							|  |  |  |  | 			UpdateTasks(); | 
					
						
							|  |  |  |  | 			UpdateTransform(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			// <20><><EFBFBD><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD>ڵ<EFBFBD>
 | 
					
						
							|  |  |  |  | 			for (; i < children_.size(); ++i) | 
					
						
							|  |  |  |  | 				children_[i]->UpdateChildren(dt); | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-10-06 09:45:28 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 	void Node::DrawBorder() | 
					
						
							| 
									
										
										
										
											2018-10-06 09:45:28 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (visible_) | 
					
						
							| 
									
										
										
										
											2018-10-06 09:45:28 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			if (border_) | 
					
						
							| 
									
										
										
										
											2018-10-06 09:45:28 +08:00
										 |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 				devices::Graphics::Instance().DrawGeometry(border_, border_color_, 1.f, 1.5f); | 
					
						
							| 
									
										
										
										
											2018-10-06 09:45:28 +08:00
										 |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 			for (const auto& child : children_) | 
					
						
							| 
									
										
										
										
											2018-10-06 09:45:28 +08:00
										 |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 				child->DrawBorder(); | 
					
						
							| 
									
										
										
										
											2018-10-06 09:45:28 +08:00
										 |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::UpdateTransform() | 
					
						
							| 
									
										
										
										
											2018-07-07 18:04:18 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (!dirty_transform_) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		dirty_transform_ = false; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		final_matrix_ = transform_.ToMatrix(); | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD><D6A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Initial <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӽڵ㽫<DAB5><E3BDAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б任
 | 
					
						
							|  |  |  |  | 		auto pivot = Point( | 
					
						
							|  |  |  |  | 			transform_.size.width * transform_.pivot_x, | 
					
						
							|  |  |  |  | 			transform_.size.height * transform_.pivot_y | 
					
						
							|  |  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		initial_matrix_ = final_matrix_ * math::Matrix::Translation(pivot); | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if (parent_) | 
					
						
							| 
									
										
										
										
											2018-09-01 23:00:08 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			initial_matrix_ = initial_matrix_ * parent_->initial_matrix_; | 
					
						
							|  |  |  |  | 			final_matrix_ = final_matrix_ * parent_->initial_matrix_; | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-07-07 18:04:18 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		// <20><><EFBFBD>¹<EFBFBD><C2B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 		SafeRelease(border_); | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		ThrowIfFailed( | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			devices::Graphics::Instance().CreateRectGeometry(final_matrix_, transform_.size, &border_) | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// ֪ͨ<CDA8>ӽڵ<D3BD><DAB5><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>
 | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 		for (const auto& child : children_) | 
					
						
							| 
									
										
										
										
											2018-07-28 18:44:37 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			child->dirty_transform_ = true; | 
					
						
							| 
									
										
										
										
											2018-07-28 18:44:37 +08:00
										 |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-07-07 18:04:18 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-01 17:53:56 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	bool Node::Dispatch(const MouseEvent & e, bool handled) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (visible_) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			for (auto riter = children_.crbegin(); riter != children_.crend(); ++riter) | 
					
						
							|  |  |  |  | 				handled = (*riter)->Dispatch(e, handled); | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			auto handler = dynamic_cast<MouseEventHandler*>(this); | 
					
						
							|  |  |  |  | 			if (handler) | 
					
						
							|  |  |  |  | 				handler->Handle(e); | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-09-16 16:07:51 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		return handled; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-11 00:37:52 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	bool Node::Dispatch(const KeyEvent & e, bool handled) | 
					
						
							| 
									
										
										
										
											2018-09-11 00:37:52 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (visible_) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			for (auto riter = children_.crbegin(); riter != children_.crend(); ++riter) | 
					
						
							|  |  |  |  | 				handled = (*riter)->Dispatch(e, handled); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			auto handler = dynamic_cast<KeyEventHandler*>(this); | 
					
						
							|  |  |  |  | 			if (handler) | 
					
						
							|  |  |  |  | 				handler->Handle(e); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		return handled; | 
					
						
							| 
									
										
										
										
											2018-09-11 00:37:52 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 	void Node::UpdateOpacity() | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (parent_) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			display_opacity_ = real_opacity_ * parent_->display_opacity_; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 		for (const auto& child : children_) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			child->UpdateOpacity(); | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::UpdateActions() | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (actions_.empty()) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 		std::vector<spAction> currActions; | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		currActions.reserve(actions_.size()); | 
					
						
							|  |  |  |  | 		std::copy_if( | 
					
						
							|  |  |  |  | 			actions_.begin(), | 
					
						
							|  |  |  |  | 			actions_.end(), | 
					
						
							|  |  |  |  | 			std::back_inserter(currActions), | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 			[](spAction action) { return action->IsRunning() && !action->IsDone(); } | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2018-09-01 23:00:08 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еĶ<D0B5><C4B6><EFBFBD>
 | 
					
						
							|  |  |  |  | 		for (const auto& action : currActions) | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 			action->Update(this); | 
					
						
							| 
									
										
										
										
											2018-09-01 23:00:08 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵĶ<C9B5><C4B6><EFBFBD>
 | 
					
						
							|  |  |  |  | 		for (auto iter = actions_.begin(); iter != actions_.end();) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if ((*iter)->IsDone()) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				iter = actions_.erase(iter); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 			else | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				++iter; | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-01 23:00:08 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	bool Node::IsVisible() const | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		return visible_; | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	const String& Node::GetName() const | 
					
						
							| 
									
										
										
										
											2018-08-12 14:30:28 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		return name_; | 
					
						
							| 
									
										
										
										
											2018-08-12 14:30:28 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	size_t Node::GetHashName() const | 
					
						
							| 
									
										
										
										
											2018-08-12 14:30:28 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		return hash_name_; | 
					
						
							| 
									
										
										
										
											2018-08-12 14:30:28 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	const Point& Node::GetPosition() const | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return transform_.position; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-07-16 22:11:27 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	float Node::GetWidth() const | 
					
						
							| 
									
										
										
										
											2018-04-24 10:35:58 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		return transform_.size.width * transform_.scale_x; | 
					
						
							| 
									
										
										
										
											2018-04-24 10:35:58 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 	float Node::GetHeight() const | 
					
						
							| 
									
										
										
										
											2017-10-15 23:58:39 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		return transform_.size.height * transform_.scale_y; | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-14 18:43:32 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	float Node::GetRealWidth() const | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return transform_.size.width; | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	float Node::GetRealHeight() const | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return transform_.size.height; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-14 18:43:32 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	const Size& Node::GetRealSize() const | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return transform_.size; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-17 21:22:25 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	float Node::GetPivotX() const | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return transform_.pivot_x; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-03-31 18:12:01 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	float Node::GetPivotY() const | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return transform_.pivot_y; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-15 02:46:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	Size Node::GetSize() const | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return Size{ GetWidth(), GetHeight() }; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-14 18:43:32 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	float Node::GetScaleX() const | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return transform_.scale_x; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-17 21:22:25 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	float Node::GetScaleY() const | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return transform_.scale_y; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-17 21:22:25 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	float Node::GetSkewX() const | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return transform_.skew_x; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-17 21:22:25 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	float Node::GetSkewY() const | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return transform_.skew_y; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-17 21:22:25 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	float Node::GetRotation() const | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return transform_.rotation; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-26 17:17:30 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	const math::Transform & Node::GetTransform() const | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return transform_; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-26 17:17:30 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	float Node::GetOpacity() const | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return real_opacity_; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	float Node::GetDisplayOpacity() const | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return display_opacity_; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	int Node::GetOrder() const | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return order_; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetOrder(int order) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (order_ == order) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		order_ = order; | 
					
						
							|  |  |  |  | 		if (parent_) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			parent_->dirty_sort_ = true; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetPositionX(float x) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		this->SetPosition(x, transform_.position.y); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetPositionY(float y) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		this->SetPosition(transform_.position.x, y); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-04-21 18:42:07 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetPosition(const Point & p) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		this->SetPosition(p.x, p.y); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetPosition(float x, float y) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (transform_.position.x == x && transform_.position.y == y) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2018-10-18 00:17:27 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		transform_.position.x = x; | 
					
						
							|  |  |  |  | 		transform_.position.y = y; | 
					
						
							|  |  |  |  | 		dirty_transform_ = true; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-15 02:46:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::MoveBy(float x, float y) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		this->SetPosition(transform_.position.x + x, transform_.position.y + y); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-07-28 18:44:37 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::MoveBy(const Point & v) | 
					
						
							| 
									
										
										
										
											2018-07-28 18:44:37 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		this->MoveBy(v.x, v.y); | 
					
						
							| 
									
										
										
										
											2018-07-28 18:44:37 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetScaleX(float scale_x) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		this->SetScale(scale_x, transform_.scale_y); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetScaleY(float scale_y) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		this->SetScale(transform_.scale_x, scale_y); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetScale(float scale) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		this->SetScale(scale, scale); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetScale(float scale_x, float scale_y) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (transform_.scale_x == scale_x && transform_.scale_y == scale_y) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2018-05-07 17:15:57 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		transform_.scale_x = scale_x; | 
					
						
							|  |  |  |  | 		transform_.scale_y = scale_y; | 
					
						
							|  |  |  |  | 		dirty_transform_ = true; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-05-07 17:15:57 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetSkewX(float skew_x) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		this->SetSkew(skew_x, transform_.skew_y); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-23 16:37:51 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetSkewY(float skew_y) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		this->SetSkew(transform_.skew_x, skew_y); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-23 16:37:51 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetSkew(float skew_x, float skew_y) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (transform_.skew_x == skew_x && transform_.skew_y == skew_y) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2017-10-17 21:22:25 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		transform_.skew_x = skew_x; | 
					
						
							|  |  |  |  | 		transform_.skew_y = skew_y; | 
					
						
							|  |  |  |  | 		dirty_transform_ = true; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetRotation(float angle) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (transform_.rotation == angle) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		transform_.rotation = angle; | 
					
						
							|  |  |  |  | 		dirty_transform_ = true; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-15 02:46:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetOpacity(float opacity) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (real_opacity_ == opacity) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		display_opacity_ = real_opacity_ = std::min(std::max(opacity, 0.f), 1.f); | 
					
						
							|  |  |  |  | 		// <20><><EFBFBD>½ڵ<C2BD><EFBFBD><CDB8><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 		UpdateOpacity(); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetPivotX(float pivot_x) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		this->SetPivot(pivot_x, transform_.pivot_y); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetPivotY(float pivot_y) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		this->SetPivot(transform_.pivot_x, pivot_y); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-15 02:46:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetPivot(float pivot_x, float pivot_y) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (transform_.pivot_x == pivot_x && transform_.pivot_y == pivot_y) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2017-10-15 02:46:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		transform_.pivot_x = pivot_x; | 
					
						
							|  |  |  |  | 		transform_.pivot_y = pivot_y; | 
					
						
							|  |  |  |  | 		dirty_transform_ = true; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-15 02:46:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetWidth(float width) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		this->SetSize(width, transform_.size.height); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-15 02:46:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetHeight(float height) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		this->SetSize(transform_.size.width, height); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-15 23:58:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetSize(float width, float height) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (transform_.size.width == width && transform_.size.height == height) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2017-10-15 23:58:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		transform_.size.width = width; | 
					
						
							|  |  |  |  | 		transform_.size.height = height; | 
					
						
							|  |  |  |  | 		dirty_transform_ = true; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-15 23:58:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetSize(const Size& size) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		this->SetSize(size.width, size.height); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-15 23:58:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	void Node::SetTransform(const math::Transform & transform) | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		transform_ = transform; | 
					
						
							|  |  |  |  | 		dirty_transform_ = true; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-15 23:58:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetClipEnabled(bool enabled) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		clip_enabled_ = enabled; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::SetBorderColor(const Color & color) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		border_color_ = color; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-03-01 19:28:22 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 	void Node::AddChild(spNode const& child, int order) | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 		E2D_WARNING_IF(!child, "Node::AddChild NULL pointer exception."); | 
					
						
							| 
									
										
										
										
											2018-03-01 19:28:22 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (child) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 			if (child->parent_) | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				throw std::runtime_error("<EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>и<EFBFBD><EFBFBD>ڵ<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>"); | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-03-01 19:28:22 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 			for (Node * parent = this; parent; parent = parent->GetParent().Get()) | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				if (child == parent) | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  | 					throw std::runtime_error("һ<EFBFBD><EFBFBD><EFBFBD>ڵ㲻<EFBFBD><EFBFBD>ͬʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӽڵ<EFBFBD>"); | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-03-01 19:28:22 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			children_.push_back(child); | 
					
						
							|  |  |  |  | 			child->SetOrder(order); | 
					
						
							|  |  |  |  | 			child->parent_ = this; | 
					
						
							| 
									
										
										
										
											2018-03-01 19:28:22 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			// <20><><EFBFBD><EFBFBD><EFBFBD>ӽڵ<D3BD><EFBFBD><CDB8><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 			child->UpdateOpacity(); | 
					
						
							|  |  |  |  | 			// <20><><EFBFBD>½ڵ<C2BD>ת<EFBFBD><D7AA>
 | 
					
						
							|  |  |  |  | 			child->dirty_transform_ = true; | 
					
						
							|  |  |  |  | 			// <20><><EFBFBD><EFBFBD><EFBFBD>ӽڵ<D3BD><DAB5><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 			dirty_sort_ = true; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-04-21 18:42:07 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::AddChild(const Nodes& nodes, int order) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		for (const auto& node : nodes) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			this->AddChild(node, order); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-07-28 18:44:37 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 	spNode Node::GetParent() const | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return parent_; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-01 23:00:08 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 	Nodes Node::GetChildren(const String& name) const | 
					
						
							| 
									
										
										
										
											2017-10-14 11:40:47 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		Nodes children; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		size_t hash_code = std::hash<String>{}(name); | 
					
						
							| 
									
										
										
										
											2018-02-03 22:04:43 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		for (const auto& child : children_) | 
					
						
							| 
									
										
										
										
											2017-10-14 11:40:47 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			// <20><>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF>ܻ<EFBFBD><DCBB><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC> Hash ֵ<><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȱȽ<C8B1> Hash <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD>
 | 
					
						
							|  |  |  |  | 			if (child->hash_name_ == hash_code && child->name_ == name) | 
					
						
							| 
									
										
										
										
											2018-05-24 00:58:16 +08:00
										 |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 				children.push_back(child); | 
					
						
							| 
									
										
										
										
											2018-05-24 00:58:16 +08:00
										 |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-10-14 11:40:47 +08:00
										 |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		return children; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 	spNode Node::GetChild(const String& name) const | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		size_t hash_code = std::hash<String>{}(name); | 
					
						
							| 
									
										
										
										
											2017-10-14 18:43:32 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		for (const auto& child : children_) | 
					
						
							| 
									
										
										
										
											2017-10-17 21:22:25 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			// <20><>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF>ܻ<EFBFBD><DCBB><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC> Hash ֵ<><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȱȽ<C8B1> Hash <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD>
 | 
					
						
							|  |  |  |  | 			if (child->hash_name_ == hash_code && child->name_ == name) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				return child; | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-10-17 21:22:25 +08:00
										 |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		return nullptr; | 
					
						
							| 
									
										
										
										
											2017-10-14 11:40:47 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 	const std::vector<spNode>& Node::GetAllChildren() const | 
					
						
							| 
									
										
										
										
											2018-03-31 18:12:01 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		return children_; | 
					
						
							| 
									
										
										
										
											2018-03-31 18:12:01 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-12 23:34:13 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	int Node::GetChildrenCount() const | 
					
						
							| 
									
										
										
										
											2017-10-14 11:40:47 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		return static_cast<int>(children_.size()); | 
					
						
							| 
									
										
										
										
											2017-10-14 11:40:47 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::RemoveFromParent() | 
					
						
							| 
									
										
										
										
											2018-04-24 13:28:21 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (parent_) | 
					
						
							| 
									
										
										
										
											2018-04-24 13:28:21 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			parent_->RemoveChild(this); | 
					
						
							| 
									
										
										
										
											2018-04-24 13:28:21 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 	bool Node::RemoveChild(spNode const& child) | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 		E2D_WARNING_IF(!child, "Node::RemoveChildren NULL pointer exception."); | 
					
						
							| 
									
										
										
										
											2018-02-03 22:04:43 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (children_.empty()) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			return false; | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-02-03 22:04:43 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (child) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			auto iter = std::find(children_.begin(), children_.end(), child); | 
					
						
							|  |  |  |  | 			if (iter != children_.end()) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				children_.erase(iter); | 
					
						
							|  |  |  |  | 				child->parent_ = nullptr; | 
					
						
							|  |  |  |  | 				return true; | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-08-23 16:37:51 +08:00
										 |  |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2017-10-14 18:43:32 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	void Node::RemoveChildren(const String& child_name) | 
					
						
							| 
									
										
										
										
											2017-10-14 18:43:32 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (children_.empty()) | 
					
						
							| 
									
										
										
										
											2017-10-14 18:43:32 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			return; | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-02-03 22:04:43 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		size_t hash_code = std::hash<String>{}(child_name); | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		for (auto iter = children_.begin(); iter != children_.end();) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if ((*iter)->hash_name_ == hash_code && (*iter)->name_ == child_name) | 
					
						
							| 
									
										
										
										
											2018-05-21 23:04:58 +08:00
										 |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 				(*iter)->parent_ = nullptr; | 
					
						
							|  |  |  |  | 				iter = children_.erase(iter); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 			else | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				++iter; | 
					
						
							| 
									
										
										
										
											2017-10-14 18:43:32 +08:00
										 |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-14 11:40:47 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::RemoveAllChildren() | 
					
						
							| 
									
										
										
										
											2017-10-14 18:43:32 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		children_.clear(); | 
					
						
							| 
									
										
										
										
											2017-10-14 18:43:32 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 	void Node::RunAction(spAction const& action) | 
					
						
							| 
									
										
										
										
											2017-10-14 18:43:32 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 		E2D_WARNING_IF(!action, "Action NULL pointer exception!"); | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if (action) | 
					
						
							| 
									
										
										
										
											2017-10-14 18:43:32 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 			auto iter = std::find(actions_.begin(), actions_.end(), action); | 
					
						
							|  |  |  |  | 			if (iter == actions_.end()) | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 				action->Start(); | 
					
						
							|  |  |  |  | 				actions_.push_back(action); | 
					
						
							| 
									
										
										
										
											2018-09-16 16:07:51 +08:00
										 |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-10-14 18:43:32 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-14 11:40:47 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	void Node::ResumeAction(const String& name) | 
					
						
							| 
									
										
										
										
											2017-10-17 21:22:25 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (actions_.empty()) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2017-10-17 21:22:25 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		for (const auto& action : actions_) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (action->GetName() == name) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				action->Resume(); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	void Node::PauseAction(const String& name) | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (actions_.empty()) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		for (const auto& action : actions_) | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			if (action->GetName() == name) | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 				action->Pause(); | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	void Node::StopAction(const String& name) | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (actions_.empty()) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		for (const auto& action : actions_) | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			if (action->GetName() == name) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				action->Stop(); | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-19 00:50:04 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	bool Node::ContainsPoint(const Point& point) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (transform_.size.width == 0.f || transform_.size.height == 0.f) | 
					
						
							|  |  |  |  | 			return false; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		UpdateTransform(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		BOOL ret = 0; | 
					
						
							|  |  |  |  | 		ThrowIfFailed( | 
					
						
							|  |  |  |  | 			border_->FillContainsPoint( | 
					
						
							|  |  |  |  | 				D2D1::Point2F(point.x, point.y), | 
					
						
							|  |  |  |  | 				D2D1::Matrix3x2F::Identity(), | 
					
						
							|  |  |  |  | 				&ret | 
					
						
							|  |  |  |  | 			) | 
					
						
							|  |  |  |  | 		); | 
					
						
							|  |  |  |  | 		return ret != 0; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 	bool Node::Intersects(spNode const& node) | 
					
						
							| 
									
										
										
										
											2017-10-19 12:47:36 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (transform_.size.width == 0.f || transform_.size.height == 0.f || node->transform_.size.width == 0.f || node->transform_.size.height == 0.f) | 
					
						
							|  |  |  |  | 			return false; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 		UpdateTransform(); | 
					
						
							|  |  |  |  | 		node->UpdateTransform(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// <20><>ȡ<EFBFBD>ཻ״̬
 | 
					
						
							|  |  |  |  | 		D2D1_GEOMETRY_RELATION relation = D2D1_GEOMETRY_RELATION_UNKNOWN; | 
					
						
							|  |  |  |  | 		ThrowIfFailed( | 
					
						
							|  |  |  |  | 			border_->CompareWithGeometry( | 
					
						
							|  |  |  |  | 				node->border_, | 
					
						
							|  |  |  |  | 				D2D1::Matrix3x2F::Identity(), | 
					
						
							|  |  |  |  | 				&relation | 
					
						
							|  |  |  |  | 			) | 
					
						
							|  |  |  |  | 		); | 
					
						
							|  |  |  |  | 		return relation != D2D1_GEOMETRY_RELATION_UNKNOWN && | 
					
						
							|  |  |  |  | 			relation != D2D1_GEOMETRY_RELATION_DISJOINT; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	void Node::ResumeAllActions() | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (actions_.empty()) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		for (const auto& action : actions_) | 
					
						
							| 
									
										
										
										
											2018-03-06 09:56:17 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 			action->Resume(); | 
					
						
							| 
									
										
										
										
											2018-03-06 09:56:17 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::PauseAllActions() | 
					
						
							| 
									
										
										
										
											2018-03-06 09:56:17 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (actions_.empty()) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		for (const auto& action : actions_) | 
					
						
							| 
									
										
										
										
											2018-03-06 09:56:17 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 			action->Pause(); | 
					
						
							| 
									
										
										
										
											2018-03-06 09:56:17 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::StopAllActions() | 
					
						
							| 
									
										
										
										
											2018-03-06 09:56:17 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (actions_.empty()) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		for (const auto& action : actions_) | 
					
						
							| 
									
										
										
										
											2018-03-06 09:56:17 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 			action->Stop(); | 
					
						
							| 
									
										
										
										
											2018-03-06 09:56:17 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 	const Actions& Node::GetAllActions() const | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		return actions_; | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 	void Node::AddTask(spTask const& task) | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (task) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			auto iter = std::find(tasks_.begin(), tasks_.end(), task); | 
					
						
							|  |  |  |  | 			if (iter == tasks_.end()) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 				task->last_time_ = time::Now(); | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 				tasks_.push_back(task); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-21 19:09:31 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	void Node::StopTasks(const String& name) | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		for (const auto& task : tasks_) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (task->GetName() == name) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				task->Stop(); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	void Node::StartTasks(const String& name) | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		for (const auto& task : tasks_) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (task->GetName() == name) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				task->Start(); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	void Node::RemoveTasks(const String& name) | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		for (const auto& task : tasks_) | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			if (task->GetName() == name) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				task->stopped_ = true; | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::StopAllTasks() | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		for (const auto& task : tasks_) | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			task->Stop(); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::StartAllTasks() | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		for (const auto& task : tasks_) | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			task->Start(); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::RemoveAllTasks() | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		for (const auto& task : tasks_) | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			task->stopped_ = true; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 	const Tasks & Node::GetAllTasks() const | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		return tasks_; | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::UpdateTasks() | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (tasks_.empty()) | 
					
						
							|  |  |  |  | 			return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 		std::vector<spTask> currTasks; | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		currTasks.reserve(tasks_.size()); | 
					
						
							|  |  |  |  | 		std::copy_if( | 
					
						
							|  |  |  |  | 			tasks_.begin(), | 
					
						
							|  |  |  |  | 			tasks_.end(), | 
					
						
							|  |  |  |  | 			std::back_inserter(currTasks), | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 			[](spTask const& task) { return task->IsReady() && !task->stopped_; } | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 		for (const auto& task : currTasks) | 
					
						
							|  |  |  |  | 			task->Update(); | 
					
						
							| 
									
										
										
										
											2018-09-16 16:07:51 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 		for (auto iter = tasks_.begin(); iter != tasks_.end();) | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 			if ((*iter)->stopped_) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				iter = tasks_.erase(iter); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 			else | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				++iter; | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 	void Node::UpdateTime() | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		for (const auto& action : actions_) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			action->ResetTime(); | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		for (const auto& task : tasks_) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			task->ResetTime(); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		for (const auto& child : children_) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			child->UpdateTime(); | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-09-07 18:20:07 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-11 16:32:12 +08:00
										 |  |  |  | 	void Node::SetVisible(bool val) | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-11 16:32:12 +08:00
										 |  |  |  | 		visible_ = val; | 
					
						
							| 
									
										
										
										
											2018-09-05 00:08:03 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-21 19:09:31 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	void Node::SetName(const String& name) | 
					
						
							| 
									
										
										
										
											2017-10-14 11:40:47 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		if (name_ != name) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			// <20><><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>
 | 
					
						
							|  |  |  |  | 			name_ = name; | 
					
						
							|  |  |  |  | 			// <20><><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD> Hash <20><>
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 			hash_name_ = std::hash<String>{}(name); | 
					
						
							| 
									
										
										
										
											2018-11-08 00:21:59 +08:00
										 |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-10-14 11:40:47 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-17 21:22:25 +08:00
										 |  |  |  | } |