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

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
[0.008s][warning][cds] Archived non-system classes are disabled because the java.system.class.loader property is specified (value = "com.intellij.util.lang.PathClassLoader"). To use archived non-system classes, this property must not be set 2025-09-04 19:34:52,703 [ 48] WARN - #c.i.p.i.b.AppStarter - Unable to load JNA library (Linux/6.8.0-78-generic, jna.boot.library.path=/home/user/pycharm-2025.2.1.1/lib/jna/aarch64) java.lang.UnsatisfiedLinkError: Unable to locate JNA native support library at com.sun.jna.Native.loadNativeDispatchLibrary(Native.java:1014) at com.sun.jna.Native.<clinit>(Native.java:221) at com.intellij.jna.JnaLoader.load(JnaLoader.java:29) at com.intellij.platform.ide.bootstrap.StartupUtil$scheduleLoadSystemLibsAndLogInfoAndInitMacApp$1$2.invokeSuspend(startup.kt:353) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) at kotlinx.coroutines.internal.SoftLimitedDispatcher$Worker.run(SoftLimitedDispatcher.kt:130) at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:89) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:613) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:1183) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:778) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:765) **Start Failed** Internal error java.awt.HeadlessException: No X11 DISPLAY variable was set, or no headful library support was found, but this program performed an operation which requires it, at java.desktop/java.awt.dnd.DragSource.getDefaultDragSource(DragSource.java:226) at com.intellij.platform.ide.bootstrap.UiKt$scheduleUpdateFrameClassAndWindowIconAndPreloadSystemFonts$1$3.invokeSuspend(ui.kt:267) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714) at java.base/java.security.AccessController.doPrivileged(AccessController.java:400) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742) at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.kt:276) 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) ----- JRE: 21.0.8+9-Ubuntu-0ubuntu122.04.1 amd64 (Ubuntu) /usr/lib/jvm/java-21-openjdk-amd64
最新发布
09-05
2025-07-25 11:02:25,669 INFO o.a.j.g.a.Load: Loading file: E:\workraunjian\jmeter\apache-jmeter-5.4\bin\TESTJMX\yuhangyingji.jmx 2025-07-25 11:02:25,670 INFO o.a.j.s.FileServer: Set new base='E:\workraunjian\jmeter\apache-jmeter-5.4\bin\TESTJMX' 2025-07-25 11:02:25,670 INFO o.a.j.s.SaveService: Loading file: E:\workraunjian\jmeter\apache-jmeter-5.4\bin\TESTJMX\yuhangyingji.jmx 2025-07-25 11:02:25,796 WARN o.a.j.g.a.Load: Unexpected error. java.lang.NullPointerException java.lang.NullPointerException: null at java.util.ArrayDeque.addLast(ArrayDeque.java:303) ~[?:?] at java.util.ArrayDeque.add(ArrayDeque.java:494) ~[?:?] at org.apache.jmeter.gui.action.LoadRecentProject.updateRecentFileMenuItems(LoadRecentProject.java:125) ~[ApacheJMeter_core.jar:5.4] at org.apache.jmeter.gui.util.JMeterMenuBar.setProjectFileLoaded(JMeterMenuBar.java:144) ~[ApacheJMeter_core.jar:5.4] at org.apache.jmeter.gui.MainFrame.setProjectFileLoaded(MainFrame.java:330) ~[ApacheJMeter_core.jar:5.4] at org.apache.jmeter.gui.GuiPackage.setTestPlanFile(GuiPackage.java:732) ~[ApacheJMeter_core.jar:5.4] at org.apache.jmeter.gui.action.Load.loadProjectFile(Load.java:136) ~[ApacheJMeter_core.jar:5.4] at org.apache.jmeter.gui.action.Load.loadProjectFile(Load.java:101) ~[ApacheJMeter_core.jar:5.4] at org.apache.jmeter.gui.action.Load.doActionAfterCheck(Load.java:88) ~[ApacheJMeter_core.jar:5.4] at org.apache.jmeter.gui.action.AbstractActionWithNoRunningTest.doAction(AbstractActionWithNoRunningTest.java:44) ~[ApacheJMeter_core.jar:5.4] at org.apache.jmeter.gui.action.ActionRouter.performAction(ActionRouter.java:87) ~[ApacheJMeter_core.jar:5.4] at org.apache.jmeter.gui.action.ActionRouter.lambda$actionPerformed$0(ActionRouter.java:69) ~[ApacheJMeter_core.jar:5.4] at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318) ~[?:?] at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773) ~[?:?] at java.awt.EventQueue$4.run(EventQueue.java:720) ~[?:?] at java.awt.EventQueue$4.run(EventQueue.java:714) ~[?:?] at java.security.AccessController.doPrivileged(AccessController.java:399) [?:?] at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) [?:?] at java.awt.EventQueue.dispatchEvent(EventQueue.java:742) [?:?] at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) [?:?] at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) [?:?] at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) [?:?] at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) [?:?] at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) [?:?] at java.awt.EventDispatchThread.run(EventDispatchThread.java:90) [?:?] 2025-07-25 11:02:25,797 ERROR o.a.j.u.JMeterUtils: Unexpected error - see log for details
07-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值