EventDispatch机制

本文深入探讨了Cocos2d-x3.x中的事件机制,包括通过访问Node的全局Zorder来排列优先级的过程。文章详细解释了如何遍历Scene下的所有子Layer,将比当前Layer优先级数小的节点存放在_nodePriorityMap中,并清除子Layer中优先级小的节点。此外,文章还介绍了每个Node的sortChildren操作以及二叉树中序遍历的类比,用于理解事件的派发过程。

cocos2dx 3.x中的事件机制原理:

通过访问Node的全局Zorder来排列优先级。

            _globalZOrderNodeMap[node->getGlobalZOrder()].push_back(node);


_globalZOrderNodeMap 作为迭代的容器,最后处理根节点排序的结果(会清理掉当前存放的节点),真正有效的数据时排列好的:_nodePriorityMap。

首先遍历Scene下的所有子Layer(Node*),把子节点中比当前Layer优先级数值小的存放在_nodePriorityMap,接着清除子Layer中比当前Layer优先级小的节点,然后把当前节点放入_globalZOrderNodeMap 。

每个Node都有一个sortChildren操作,排列出来的就是根据Zorder,只要先处理比当前Layer深度优先的(Zorder),再处理当前layer,和小于或等于的Children——整个原理就跟二叉树中序遍历比较类似,判定条件是Zorder。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. oid EventDispatcher::visitTarget(Node* node, bool isRootNode)  
  2. {      
  3.     int i = 0;  
  4.     auto& children = node->getChildren();  
  5.       
  6.     auto childrenCount = children.size();  
  7.       
  8.     if(childrenCount > 0)  
  9.     {  
  10.         Node* child = nullptr;  
  11.         // visit children zOrder < 0  
  12.         for( ; i < childrenCount; i++ )  
  13.         {  
  14.             child = children.at(i);  
  15.               
  16.             if ( child && child->getLocalZOrder() < 0 )  
  17.                 visitTarget(child, false);  
  18.             else  
  19.                 break;  
  20.         }  
  21.           
  22.         if (_nodeListenersMap.find(node) != _nodeListenersMap.end())  
  23.         {  
  24.             _globalZOrderNodeMap[node->getGlobalZOrder()].push_back(node);  
  25.         }  
  26.           
  27.         for( ; i < childrenCount; i++ )  
  28.         {  
  29.             child = children.at(i);  
  30.             if (child)  
  31.                 visitTarget(child, false);  
  32.         }  
  33.     }  
  34.     else  
  35.     {  
  36.         if (_nodeListenersMap.find(node) != _nodeListenersMap.end())  
  37.         {  
  38.             _globalZOrderNodeMap[node->getGlobalZOrder()].push_back(node);  
  39.         }  
  40.     }  
  41.     //递归的所有过程中只有根节点进入(Scene),事件的派发级是依据<span style="font-family: Arial, Helvetica, sans-serif;">_nodePriorityMap中的结果去派发</span>  
  42.   
  43.     if (isRootNode)  
  44.     {  
  45.         std::vector<float> globalZOrders;  
  46.         globalZOrders.reserve(_globalZOrderNodeMap.size());  
  47.           
  48.         for (const auto& e : _globalZOrderNodeMap)  
  49.         {  
  50.             globalZOrders.push_back(e.first);  
  51.         }  
  52.           
  53.         std::sort(globalZOrders.begin(), globalZOrders.end(), [](const float a, const float b){  
  54.             return a < b;  
  55.         });  
  56.           
  57.         for (const auto& globalZ : globalZOrders)  
  58.         {  
  59.             for (const auto& n : _globalZOrderNodeMap[globalZ])  
  60.             {  
  61.                 _nodePriorityMap[n] = ++_nodePriorityIndex;  
  62.             }  
  63.         }  
  64.           
  65.         _globalZOrderNodeMap.clear();  
  66.     }  
  67. }  


_nodePriorityIndex 为SceneGraphPriority控制量,最后组合成从0到N不重复的数字队列,去标示每个Node,所有的Node具有不同的优先级。

来源:http://blog.youkuaiyun.com/jingzhewangzi/article/details/40644955

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at com.chenluozhi.util.DBConnection.query(DBConnection.java:52) at com.chenluozhi.dao.UserDao.userLogin(UserDao.java:40) at com.chenluozhi.frame.Login$BtnListener.actionPerformed(Login.java:231) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252) at java.awt.Component.processMouseEvent(Component.java:6533) at javax.swing.JComponent.processMouseEvent(JComponent.java:3324) at java.awt.Component.processEvent(Component.java:6298) at java.awt.Container.processEvent(Container.java:2236) at java.awt.Component.dispatchEventImpl(Component.java:4889) at java.awt.Container.dispatchEventImpl(Container.java:2294) at java.awt.Component.dispatchEvent(Component.java:4711) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466) at java.awt.Container.dispatchEventImpl(Container.java:2280) at java.awt.Window.dispatchEventImpl(Window.java:2746) at java.awt.Component.dispatchEvent(Component.java:4711) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758) at java.awt.EventQueue.access$500(EventQueue.java:97) at java.awt.EventQueue$3.run(EventQueue.java:709) at java.awt.EventQueue$3.run(EventQueue.java:703) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90) at java.awt.EventQueue$4.run(EventQueue.java:731) at java.awt.EventQueue$4.run(EventQueue.java:729) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80) at java.awt.EventQueue.dispatchEvent(EventQueue.java:728) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)以上代码显示什么错误
最新发布
07-06
java.io.FileNotFoundException: http://localhost:8080/api/course/list at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1913) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1515) at com.ndky.StudentManagementGUI.sendGetRequest(StudentManagementGUI.java:355) at com.ndky.StudentManagementGUI.refreshTable(StudentManagementGUI.java:115) at com.ndky.StudentManagementGUI.lambda$openWindow$6(StudentManagementGUI.java:107) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:262) at java.awt.Component.processMouseEvent(Component.java:6539) at javax.swing.JComponent.processMouseEvent(JComponent.java:3324) at java.awt.Component.processEvent(Component.java:6304) at java.awt.Container.processEvent(Container.java:2239) at java.awt.Component.dispatchEventImpl(Component.java:4889) at java.awt.Container.dispatchEventImpl(Container.java:2297) at java.awt.Component.dispatchEvent(Component.java:4711) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4904) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4535) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4476) at java.awt.Container.dispatchEventImpl(Container.java:2283) at java.awt.Window.dispatchEventImpl(Window.java:2746) at java.awt.Component.dispatchEvent(Component.java:4711) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760) at java.awt.EventQueue.access$500(EventQueue.java:97) at java.awt.EventQueue$3.run(EventQueue.java:709) at java.awt.EventQueue$3.run(EventQueue.java:703) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:84) at java.awt.EventQueue$4.run(EventQueue.java:733) at java.awt.EventQueue$4.run(EventQueue.java:731) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74) at java.awt.EventQueue.dispatchEvent(EventQueue.java:730) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
06-12
java.sql.SQLSyntaxErrorException: Table 'library.borrow_records' doesn't exist at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:112) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:114) at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:990) at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1168) at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1103) at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1450) at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1086) at service.BorrowReturnManage.borrowBook(BorrowReturnManage.java:60) at ui.LibrarySystemUI.lambda$initBorrowBookPanel$1(LibrarySystemUI.java:689) at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972) at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2314) at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:407) at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262) at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279) at java.desktop/java.awt.Component.processMouseEvent(Component.java:6576) at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3404) at java.desktop/java.awt.Component.processEvent(Component.java:6341) at java.desktop/java.awt.Container.processEvent(Container.java:2260) at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4958) at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2318) at java.desktop/java.awt.Component.dispatchEvent(Component.java:4790) at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4916) at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4559) at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4500) at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2304) at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2671) at java.desktop/java.awt.Component.dispatchEvent(Component.java:4790) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:725) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:702) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
06-26
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值